Vital
Loading...
Searching...
No Matches
delay_section.h
Go to the documentation of this file.
1
3
4#pragma once
5
6#include "JuceHeader.h"
7#include "delay.h"
9#include "synth_section.h"
10
11class DelayViewer;
12class SynthButton;
13class SynthSlider;
14class TempoSelector;
15class TextSelector;
16
24 public:
26 static constexpr float kMidiDrawStart = 8.0f;
27 static constexpr float kMidiDrawEnd = 132.0f;
29 static constexpr float kMinDb = -18.0f;
30 static constexpr float kMaxDb = 6.0f;
31
34 class Listener {
35 public:
36 virtual ~Listener() = default;
40 virtual void deltaMovement(float x, float y) = 0;
41 };
42
47 DelayFilterViewer(const std::string& prefix, int resolution, const vital::output_map& mono_modulations) :
48 OpenGlLineRenderer(resolution), active_(true), cutoff_slider_(nullptr), spread_slider_(nullptr) {
49 setFill(true);
50 setFillCenter(-1.0f);
51
52 cutoff_ = mono_modulations.at(prefix + "_cutoff");
53 spread_ = mono_modulations.at(prefix + "_spread");
54 }
55
58 if (cutoff_slider_ && !cutoff_->owner->enabled())
59 return cutoff_slider_->getValue();
60 return cutoff_->trigger_value;
61 }
62
65 if (spread_slider_ && !spread_->owner->enabled())
66 return spread_slider_->getValue();
67 return spread_->trigger_value;
68 }
69
70
72 void drawLines(OpenGlWrapper& open_gl, bool animate, float high_midi_cutoff, float low_midi_cutoff) {
73 float midi_increment = (kMidiDrawEnd - kMidiDrawStart) / (numPoints() - 1);
74 float mult_increment = vital::utils::centsToRatio(midi_increment * vital::kCentsPerNote);
75
76 float high_midi_offset_start = kMidiDrawStart - high_midi_cutoff;
77 float high_ratio = vital::utils::centsToRatio(high_midi_offset_start * vital::kCentsPerNote);
78 float low_midi_offset_start = kMidiDrawStart - low_midi_cutoff;
79 float low_ratio = vital::utils::centsToRatio(low_midi_offset_start * vital::kCentsPerNote);
80
81 float gain = vital::utils::centsToRatio((high_midi_cutoff - low_midi_cutoff) * vital::kCentsPerNote) + 1.0f;
82
83 float width = getWidth();
84 float height = getHeight();
85 int num_points = numPoints();
86 for (int i = 0; i < num_points; ++i) {
87 float high_response = high_ratio / sqrtf(1 + high_ratio * high_ratio);
88 float low_response = 1.0f / sqrtf(1 + low_ratio * low_ratio);
89 float response = gain * low_response * high_response;
90 float db = vital::utils::magnitudeToDb(response);
91 float y = (db - kMinDb) / (kMaxDb - kMinDb);
92
93 setXAt(i, width * i / (num_points - 1.0f));
94 setYAt(i, (1.0f - y) * height);
95
96 high_ratio *= mult_increment;
97 low_ratio *= mult_increment;
98 }
99
100 OpenGlLineRenderer::render(open_gl, animate);
101 }
102
106 void render(OpenGlWrapper& open_gl, bool animate) override {
107 vital::poly_float cutoff = getCutoff();
109 vital::poly_float high_midi_cutoff = cutoff - radius;
110 vital::poly_float low_midi_cutoff = cutoff + radius;
111
114
115 float fill_fade = findValue(Skin::kWidgetFillFade);
116 Colour color_fill_to;
117 if (active_) {
118 setColor(findColour(Skin::kWidgetPrimary1, true));
119 color_fill_to = findColour(Skin::kWidgetSecondary1, true);
120 }
121 else {
122 setColor(findColour(Skin::kWidgetPrimaryDisabled, true));
123 color_fill_to = findColour(Skin::kWidgetSecondaryDisabled, true);
124 }
125
126 Colour color_fill_from = color_fill_to.withMultipliedAlpha(1.0f - fill_fade);
127 setFillColors(color_fill_from, color_fill_to);
128 drawLines(open_gl, animate, high_midi_cutoff[0], low_midi_cutoff[0]);
129
130 if (active_) {
131 setColor(findColour(Skin::kWidgetPrimary2, true));
132 color_fill_to = findColour(Skin::kWidgetSecondary2, true);
133 }
134 else {
135 setColor(findColour(Skin::kWidgetPrimaryDisabled, true));
136 color_fill_to = findColour(Skin::kWidgetSecondaryDisabled, true);
137 }
138 color_fill_from = color_fill_to.withMultipliedAlpha(1.0f - fill_fade);
139 setFillColors(color_fill_from, color_fill_to);
140 drawLines(open_gl, animate, high_midi_cutoff[1], low_midi_cutoff[1]);
141
142 renderCorners(open_gl, animate);
143 }
144
147 void mouseDown(const MouseEvent& e) override {
148 last_mouse_position_ = e.getPosition();
149 }
150
153 void mouseDrag(const MouseEvent& e) override {
154 Point<int> delta = e.getPosition() - last_mouse_position_;
155 last_mouse_position_ = e.getPosition();
156
157 for (Listener* listener : listeners_)
158 listener->deltaMovement(delta.x * 1.0f / getWidth(), -delta.y * 1.0f / getHeight());
159 }
160
163 void setCutoffSlider(Slider* slider) { cutoff_slider_ = slider; }
164
167 void setSpreadSlider(Slider* slider) { spread_slider_ = slider; }
168
171 void setActive(bool active) { active_ = active; }
172
175 void addListener(Listener* listener) { listeners_.push_back(listener); }
176
177 private:
178 bool active_;
179 std::vector<Listener*> listeners_;
180 Point<int> last_mouse_position_;
181
182 vital::Output* cutoff_;
183 vital::Output* spread_;
184 Slider* cutoff_slider_;
185 Slider* spread_slider_;
186
187 JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(DelayFilterViewer)
188};
189
198 public:
199
203 DelaySection(const String& name, const vital::output_map& mono_modulations);
204
206 virtual ~DelaySection();
207
210 void paintBackground(Graphics& g) override;
211
214 void paintBackgroundShadow(Graphics& g) override { if (isActive()) paintTabShadow(g); }
215
217 void resized() override;
218
221 void setActive(bool active) override;
222
224 void resizeTempoControls();
225
228 void setAllValues(vital::control_map& controls) override {
231 }
232
235 void sliderValueChanged(Slider* changed_slider) override;
236
240 void deltaMovement(float x, float y) override;
241
242 private:
243 std::unique_ptr<SynthButton> on_;
244 std::unique_ptr<SynthSlider> frequency_;
245 std::unique_ptr<SynthSlider> tempo_;
246 std::unique_ptr<TempoSelector> sync_;
247 std::unique_ptr<SynthSlider> aux_frequency_;
248 std::unique_ptr<SynthSlider> aux_tempo_;
249 std::unique_ptr<TempoSelector> aux_sync_;
250 std::unique_ptr<SynthSlider> feedback_;
251 std::unique_ptr<SynthSlider> dry_wet_;
252 std::unique_ptr<SynthSlider> filter_cutoff_;
253 std::unique_ptr<SynthSlider> filter_spread_;
254 std::unique_ptr<TextSelector> style_;
255
256 std::unique_ptr<DelayFilterViewer> delay_filter_viewer_;
257 std::unique_ptr<DelayViewer> delay_viewer_;
258
259 JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(DelaySection)
260};
261
Interface for objects that want to respond to mouse drag movements in the filter viewer.
Definition delay_section.h:34
virtual void deltaMovement(float x, float y)=0
virtual ~Listener()=default
A viewer that displays and allows interaction with the delay effect's filter response.
Definition delay_section.h:23
vital::poly_float getCutoff()
Gets the current cutoff value (modulated or from slider).
Definition delay_section.h:57
static constexpr float kMinDb
Minimum and maximum dB values for the filter response display.
Definition delay_section.h:29
void drawLines(OpenGlWrapper &open_gl, bool animate, float high_midi_cutoff, float low_midi_cutoff)
Draws the filter lines given the high and low MIDI cutoff values.
Definition delay_section.h:72
void render(OpenGlWrapper &open_gl, bool animate) override
Definition delay_section.h:106
void mouseDrag(const MouseEvent &e) override
Definition delay_section.h:153
void setActive(bool active)
Definition delay_section.h:171
void mouseDown(const MouseEvent &e) override
Definition delay_section.h:147
static constexpr float kMaxDb
Definition delay_section.h:30
void setSpreadSlider(Slider *slider)
Definition delay_section.h:167
DelayFilterViewer(const std::string &prefix, int resolution, const vital::output_map &mono_modulations)
Definition delay_section.h:47
void addListener(Listener *listener)
Definition delay_section.h:175
void setCutoffSlider(Slider *slider)
Definition delay_section.h:163
static constexpr float kMidiDrawEnd
Definition delay_section.h:27
vital::poly_float getSpread()
Gets the current spread value (modulated or from slider).
Definition delay_section.h:64
static constexpr float kMidiDrawStart
The MIDI note range for drawing the filter response.
Definition delay_section.h:26
A UI section providing controls for a delay effect, including tempo-synced delays,...
Definition delay_section.h:197
void paintBackgroundShadow(Graphics &g) override
Definition delay_section.h:214
virtual ~DelaySection()
Destructor.
void resized() override
Resizes and lays out child components, including placing tempo controls based on the delay style.
Definition delay_section.cpp:318
void resizeTempoControls()
Resizes the tempo controls depending on the delay style (e.g., mono or stereo).
Definition delay_section.cpp:354
void deltaMovement(float x, float y) override
Definition delay_section.cpp:401
DelaySection(const String &name, const vital::output_map &mono_modulations)
Definition delay_section.cpp:209
void setAllValues(vital::control_map &controls) override
Definition delay_section.h:228
void paintBackground(Graphics &g) override
Definition delay_section.cpp:296
void setActive(bool active) override
Definition delay_section.cpp:348
void sliderValueChanged(Slider *changed_slider) override
Definition delay_section.cpp:387
Definition delay_section.cpp:25
void renderCorners(OpenGlWrapper &open_gl, bool animate, Colour color, float rounding)
Renders the corner shapes using the given color and rounding amount.
Definition open_gl_component.cpp:153
float findValue(Skin::ValueId value_id)
Finds a float value from the skin associated with this component's parent.
Definition open_gl_component.cpp:173
A component for rendering lines with optional filling and boost effects using OpenGL.
Definition open_gl_line_renderer.h:16
force_inline void setFillCenter(float fill_center)
Sets the vertical center for the fill area.
Definition open_gl_line_renderer.h:138
virtual void render(OpenGlWrapper &open_gl, bool animate) override
Renders the line using OpenGL.
Definition open_gl_line_renderer.cpp:464
force_inline void setYAt(int index, float val)
Sets the y-coordinate of a point, marking data as dirty.
Definition open_gl_line_renderer.h:98
force_inline void setFill(bool fill)
Enables or disables filling below the line.
Definition open_gl_line_renderer.h:124
force_inline void setXAt(int index, float val)
Sets the x-coordinate of a point, marking data as dirty.
Definition open_gl_line_renderer.h:105
force_inline void setFillColors(Colour fill_color_from, Colour fill_color_to)
Sets a gradient fill from one color to another.
Definition open_gl_line_renderer.h:132
force_inline void setLineWidth(float width)
Sets the line width in pixels.
Definition open_gl_line_renderer.h:66
force_inline void setColor(Colour color)
Sets the line color.
Definition open_gl_line_renderer.h:63
force_inline int numPoints() const
Gets the number of points in the line.
Definition open_gl_line_renderer.h:186
@ kWidgetLineWidth
Definition skin.h:105
@ kWidgetFillCenter
Definition skin.h:107
@ kWidgetFillFade
Definition skin.h:108
@ kWidgetPrimaryDisabled
Definition skin.h:167
@ kWidgetPrimary2
Definition skin.h:166
@ kWidgetPrimary1
Definition skin.h:165
@ kWidgetSecondary1
Definition skin.h:168
@ kWidgetSecondaryDisabled
Definition skin.h:170
@ kWidgetSecondary2
Definition skin.h:169
A specialized OpenGlToggleButton with additional functionality for the Vital synth.
Definition synth_button.h:450
Base class for all synthesizer sections, providing UI layout, painting, and interaction logic.
Definition synth_section.h:193
bool isActive() const
Checks if the section is currently active.
Definition synth_section.h:683
virtual void setAllValues(vital::control_map &controls)
Sets values for all known parameters from a control map.
Definition synth_section.cpp:827
virtual void paintTabShadow(Graphics &g)
Paints a tab-like shadow effect around the component.
Definition synth_section.cpp:188
A specialized slider with extended functionality for modulation, parameter control,...
Definition synth_slider.h:314
A slider component that allows selection between different tempo modes (seconds, tempo,...
Definition tempo_selector.h:14
A specialized SynthSlider that displays a popup menu of text options.
Definition text_selector.h:14
static poly_float getFilterRadius(poly_float spread)
Computes the filter radius based on spread.
Definition delay.h:62
force_inline bool enabled() const
Checks if this Processor is enabled.
Definition processor.h:310
cr::Value gain
Relative gain for this formant stage.
Definition formant_filter.cpp:17
force_inline poly_float magnitudeToDb(poly_float value)
Converts a magnitude value to decibels (vectorized).
Definition poly_utils.h:144
force_inline poly_float centsToRatio(poly_float value)
Converts semitone cents to a linear frequency ratio (vectorized).
Definition poly_utils.h:95
std::map< std::string, Output * > output_map
Maps parameter names to Output pointers, representing output signals from various modules.
Definition synth_types.h:229
constexpr int kCentsPerNote
Number of cents per semitone.
Definition common.h:52
std::map< std::string, Value * > control_map
Maps parameter names to Value pointers representing synth control parameters.
Definition synth_types.h:214
A helper struct containing references to OpenGL context, shaders, and display scale.
Definition shaders.h:174
Holds and manages a buffer of samples (poly_float) for a Processor's output.
Definition processor.h:35
Processor * owner
Owning processor.
Definition processor.h:112
poly_float trigger_value
Trigger values for voices.
Definition processor.h:116
Represents a vector of floating-point values using SIMD instructions.
Definition poly_values.h:600