Audacity 3.2.0
DynamicRangeProcessorTransferFunctionPanel.cpp
Go to the documentation of this file.
1/* SPDX-License-Identifier: GPL-2.0-or-later */
2/*!********************************************************************
3
4 Audacity: A Digital Audio Editor
5
6 DynamicRangeProcessorTransferFunctionPanel.cpp
7
8 Matthieu Hodgkinson
9
10**********************************************************************/
12#include "AColor.h"
13#include "AllThemeResources.h"
14#include "CompressorProcessor.h"
16#include "Theme.h"
19#include "widgets/Ruler.h"
20#include <cassert>
21#include <wx/dcclient.h>
22#include <wx/graphics.h>
23
28
31 wxWindow* parent, wxWindowID winid,
32 const CompressorSettings& compressorSettings)
33 : wxPanelWrapper { parent, winid }
34 , mCompressorSettings { compressorSettings }
35{
36 SetDoubleBuffered(true);
37}
38
39namespace
40{
41constexpr auto WidthPxToDb(double x, int width, double xPixelsPerDb)
42{
43 return (x + 1 - width) / xPixelsPerDb;
44}
45
46constexpr auto WidthDbToPx(double db, int width, double xPixelsPerDb)
47{
48 return width - 1 + db * xPixelsPerDb;
49}
50
51constexpr auto HeightDbToPx(double db, double yPixelsPerDb)
52{
53 return -db * yPixelsPerDb;
54}
55
57 double kneeX, double kneeY, const wxColor& colorAtKnee, const wxSize& size,
58 const wxGraphicsContext& gc)
59{
60 using namespace DynamicRangeProcessorPanel;
61 constexpr auto w = .75;
62 const wxColor edgeColor = GetColorMix(backgroundColor, colorAtKnee, w);
63
64 const auto xf = size.GetWidth() / 2.; // "f" for "focus"
65 const auto yf = size.GetHeight() / 2.;
66 const auto radius = size.GetWidth();
67 return gc.CreateRadialGradientBrush(
68 kneeX, kneeY, xf, yf, radius, colorAtKnee, edgeColor);
69}
70
72 wxPaintDC& dc, const wxRect& rect, const CompressorSettings& settings)
73{
74 const auto X = rect.GetWidth();
75 const auto Y = rect.GetHeight();
76 const auto xPixelsPerDb =
78 const auto yPixelsPerDb =
80
81 std::vector<wxPoint2DDouble> points;
82 points.reserve(X);
83 for (int x = rect.GetX(); x < X; ++x)
84 {
85 const auto db = WidthPxToDb(x, X, xPixelsPerDb);
86 const auto y = HeightDbToPx(
88 yPixelsPerDb);
89 points.emplace_back(x, y);
90 }
91
92 using namespace DynamicRangeProcessorPanel;
93
94 const auto gc = MakeGraphicsContext(dc);
95
96 const auto kneeX = WidthDbToPx(settings.thresholdDb, X, xPixelsPerDb);
97 const auto kneeY =
98 HeightDbToPx(settings.thresholdDb + settings.makeupGainDb, yPixelsPerDb);
99
100 // Fill the area above the curve
101 wxGraphicsPath path = gc->CreatePath();
102 path.MoveToPoint(X, 0);
103 path.AddLineToPoint(0, 0);
104 std::for_each(points.begin(), points.end(), [&path](const auto& point) {
105 path.AddLineToPoint(point);
106 });
107 path.CloseSubpath();
108 gc->SetBrush(GetBrush(kneeX, kneeY, attackColor, rect.GetSize(), *gc));
109 gc->FillPath(path);
110
111 // Fill the area below the curve
112 path = gc->CreatePath();
113 path.MoveToPoint(X, Y);
114 path.AddLineToPoint(0, Y);
115 std::for_each(points.begin(), points.end(), [&path](const auto& point) {
116 path.AddLineToPoint(point);
117 });
118 path.CloseSubpath();
119 gc->SetBrush(GetBrush(kneeX, kneeY, releaseColor, rect.GetSize(), *gc));
120 gc->FillPath(path);
121
122 // Draw the curve
123 const auto gc2 = MakeGraphicsContext(dc);
125 gc2->DrawLines(points.size(), points.data());
126}
127} // namespace
128
130{
131 wxPaintDC dc(this);
132 const auto rect = DynamicRangeProcessorPanel::GetPanelRect(*this);
135 dc.SetBrush(*wxTRANSPARENT_BRUSH);
136 dc.DrawRectangle(rect);
137}
138
140{
141 Refresh();
142}
143
145{
146 return false;
147}
148
150 const
151{
152 return false;
153}
END_EVENT_TABLE()
static Settings & settings()
Definition: TrackInfo.cpp:51
static float EvaluateTransferFunction(const DynamicRangeProcessorSettings &settings, float inputDb)
wxColor GetColorMix(const wxColor &a, const wxColor &b, double aWeight)
std::unique_ptr< wxGraphicsContext > MakeGraphicsContext(const wxPaintDC &dc)
wxRect GetPanelRect(const wxPanelWrapper &panel)
auto GetBrush(double kneeX, double kneeY, const wxColor &colorAtKnee, const wxSize &size, const wxGraphicsContext &gc)
void DrawTransferFunction(wxPaintDC &dc, const wxRect &rect, const CompressorSettings &settings)