20 return slider->getValue();
28 active_(true), feedback_slider_(nullptr), mix_slider_(nullptr),
29 tempo_slider_(nullptr), frequency_slider_(nullptr), sync_slider_(nullptr),
30 aux_tempo_slider_(nullptr), aux_frequency_slider_(nullptr), aux_sync_slider_(nullptr), style_slider_(nullptr) {
35 feedback_ = mono_modulations.at(
"delay_feedback");
36 mix_ = mono_modulations.at(
"delay_dry_wet");
37 tempo_ = mono_modulations.at(
"delay_tempo");
38 frequency_ = mono_modulations.at(
"delay_frequency");
40 aux_tempo_ = mono_modulations.at(
"delay_aux_tempo");
41 aux_frequency_ = mono_modulations.at(
"delay_aux_frequency");
45 return std::max(-1.0f, std::min(1.0f, getValue(feedback_, feedback_slider_)[index]));
49 return getValue(mix_, mix_slider_);
54 return getValue(aux_frequency_, aux_frequency_slider_)[0];
55 return getValue(frequency_, frequency_slider_)[index];
59 static constexpr float kDottedMultiplier = 3.0f / 2.0f;
60 static constexpr float kTripletMultiplier = 2.0f / 3.0f;
62 Slider* sync_slider = aux_sync_slider_;
64 sync_slider = sync_slider_;
67 return kDottedMultiplier;
69 return kTripletMultiplier;
74 static constexpr float kDefaultPowerOffset = -6.0f;
76 return std::round(getValue(aux_tempo_, aux_tempo_slider_)[0]) + kDefaultPowerOffset;
77 return std::round(getValue(tempo_, tempo_slider_)[index]) + kDefaultPowerOffset;
84 if ((index == 0 && frequency_mode) || (index == 1 && aux_frequency_mode && !mono) ||
85 (index == 1 && frequency_mode && mono)) {
93 static constexpr float kMaxSeconds = 4.0f;
101 float even_increment = increment;
102 float odd_increment = increment;
106 x -= other_increment;
107 even_increment = increment + other_increment;
108 odd_increment = even_increment;
112 odd_increment = other_increment + increment;
113 even_increment = other_increment;
116 odd_increment = increment;
117 even_increment = other_increment + increment;
123 float mult_top = index ? 0.0f : 1.0f;
124 float mult_bottom = index ? -1.0f : 0.0f;
126 setY(0, mult_top * dry);
134 setY(i, mult_top * wet);
161 last_mouse_position_ = e.getPosition();
165 Point<int> delta = e.getPosition() - last_mouse_position_;
166 last_mouse_position_ = e.getPosition();
168 float feedback_range = feedback_slider_->getMaximum() - feedback_slider_->getMinimum();
169 feedback_slider_->setValue(feedback_slider_->getValue() - delta.y * feedback_range / getWidth());
186 Point<int> last_mouse_position_;
196 Slider* feedback_slider_;
198 Slider* tempo_slider_;
199 Slider* frequency_slider_;
200 Slider* sync_slider_;
201 Slider* aux_tempo_slider_;
202 Slider* aux_frequency_slider_;
203 Slider* aux_sync_slider_;
204 Slider* style_slider_;
206 JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(
DelayViewer)
210 static const double TEMPO_DRAG_SENSITIVITY = 0.3;
211 static constexpr int kViewerResolution = 64;
213 frequency_ = std::make_unique<SynthSlider>(
"delay_frequency");
215 frequency_->setSliderStyle(Slider::RotaryHorizontalVerticalDrag);
218 tempo_ = std::make_unique<SynthSlider>(
"delay_tempo");
220 tempo_->setSliderStyle(Slider::RotaryHorizontalVerticalDrag);
222 tempo_->setSensitivity(TEMPO_DRAG_SENSITIVITY);
224 sync_ = std::make_unique<TempoSelector>(
"delay_sync");
226 sync_->setSliderStyle(Slider::LinearBar);
227 sync_->setTempoSlider(tempo_.get());
228 sync_->setFreeSlider(frequency_.get());
230 aux_frequency_ = std::make_unique<SynthSlider>(
"delay_aux_frequency");
232 aux_frequency_->setSliderStyle(Slider::RotaryHorizontalVerticalDrag);
235 aux_tempo_ = std::make_unique<SynthSlider>(
"delay_aux_tempo");
237 aux_tempo_->setSliderStyle(Slider::RotaryHorizontalVerticalDrag);
239 aux_tempo_->setSensitivity(TEMPO_DRAG_SENSITIVITY);
241 aux_sync_ = std::make_unique<TempoSelector>(
"delay_aux_sync");
243 aux_sync_->setSliderStyle(Slider::LinearBar);
244 aux_sync_->setTempoSlider(aux_tempo_.get());
245 aux_sync_->setFreeSlider(aux_frequency_.get());
247 filter_cutoff_ = std::make_unique<SynthSlider>(
"delay_filter_cutoff");
249 filter_cutoff_->setSliderStyle(Slider::RotaryHorizontalVerticalDrag);
251 filter_spread_ = std::make_unique<SynthSlider>(
"delay_filter_spread");
253 filter_spread_->setSliderStyle(Slider::RotaryHorizontalVerticalDrag);
255 feedback_ = std::make_unique<SynthSlider>(
"delay_feedback");
257 feedback_->setSliderStyle(Slider::RotaryHorizontalVerticalDrag);
258 feedback_->setBipolar();
260 dry_wet_ = std::make_unique<SynthSlider>(
"delay_dry_wet");
262 dry_wet_->setSliderStyle(Slider::RotaryHorizontalVerticalDrag);
264 style_ = std::make_unique<TextSelector>(
"delay_style");
266 style_->setSliderStyle(Slider::RotaryHorizontalVerticalDrag);
270 delay_viewer_ = std::make_unique<DelayViewer>(50, mono_modulations);
271 delay_viewer_->setFeedbackSlider(feedback_.get());
272 delay_viewer_->setMixSlider(dry_wet_.get());
273 delay_viewer_->setTempoSlider(tempo_.get());
274 delay_viewer_->setFrequencySlider(frequency_.get());
275 delay_viewer_->setAuxFrequencySlider(aux_frequency_.get());
276 delay_viewer_->setAuxTempoSlider(aux_tempo_.get());
277 delay_viewer_->setAuxSyncSlider(aux_sync_.get());
278 delay_viewer_->setSyncSlider(sync_.get());
279 delay_viewer_->setStyleSlider(style_.get());
282 delay_filter_viewer_ = std::make_unique<DelayFilterViewer>(
"delay_filter", kViewerResolution, mono_modulations);
283 delay_filter_viewer_->setCutoffSlider(filter_cutoff_.get());
284 delay_filter_viewer_->setSpreadSlider(filter_spread_.get());
285 delay_filter_viewer_->addListener(
this);
288 on_ = std::make_unique<SynthButton>(
"delay_on");
300 int frequency_x = tempo_->getX();
301 int frequency_width = std::max(sync_->getRight(), aux_sync_->getRight()) - frequency_x;
303 Rectangle<int> frequency_bounds(frequency_x, widget_margin, frequency_width, section_height - 2 * widget_margin);
313 drawLabel(g, TRANS(
"FREQUENCY"), frequency_bounds,
true);
323 Rectangle<int> bounds = getLocalBounds().withLeft(title_width);
326 int knob_y2 = getHeight() - knob_section_height;
329 style_->setBounds(text_area.getX(), knob_y2 + widget_margin, text_area.getWidth(),
330 knob_section_height - 2 * widget_margin);
332 int widget_x = text_area.getRight() + widget_margin;
333 int viewer_width = knobs_area.getX() - widget_x;
334 int delay_height = (getHeight() - 3 * widget_margin) / 2;
335 delay_viewer_->setBounds(widget_x, widget_margin, viewer_width, delay_height);
337 int filter_y = delay_viewer_->getBottom() + widget_margin;
338 delay_filter_viewer_->setBounds(widget_x, filter_y, viewer_width, getHeight() - filter_y - widget_margin);
340 placeKnobsInArea(knobs_area.withBottom(knob_section_height), { feedback_.get(), dry_wet_.get() });
341 placeKnobsInArea(knobs_area.withTop(knob_y2).withHeight(knob_section_height),
342 { filter_cutoff_.get(), filter_spread_.get() });
350 delay_filter_viewer_->setActive(active);
351 delay_viewer_->setActive(active);
358 int text_component_width = style_->getWidth();
359 int text_component_height = style_->getHeight();
360 int text_control_x = style_->getX();
364 text_component_height, frequency_.get(), sync_.get());
365 tempo_->setBounds(frequency_->getBounds());
366 tempo_->setModulationArea(frequency_->getModulationArea());
368 aux_frequency_->setBounds(0, 0, 0, 0);
369 aux_sync_->setBounds(0, 0, 0, 0);
370 aux_tempo_->setBounds(0, 0, 0, 0);
373 int width = text_component_width / 2;
375 text_component_height, frequency_.get(), sync_.get());
376 tempo_->setBounds(frequency_->getBounds());
377 tempo_->setModulationArea(frequency_->getModulationArea());
379 int width2 = text_component_width - width;
381 knob_section_height - 2 * widget_margin, aux_frequency_.get(), aux_sync_.get());
382 aux_tempo_->setBounds(aux_frequency_->getBounds());
383 aux_tempo_->setModulationArea(aux_frequency_->getModulationArea());
390 if (changed_slider == style_.get()) {
391 if (aux_tempo_->getWidth() == 0) {
392 aux_tempo_->setValue(tempo_->getValue());
393 aux_sync_->setValue(sync_->getValue());
394 aux_frequency_->setValue(frequency_->getValue());
402 double x_range = filter_cutoff_->getMaximum() - filter_cutoff_->getMinimum();
403 double y_range = filter_spread_->getMaximum() - filter_spread_->getMinimum();
405 filter_cutoff_->setValue(filter_cutoff_->getValue() + x * x_range);
406 filter_spread_->setValue(filter_spread_->getValue() + y * y_range);
A renderer for drawing a series of bars using OpenGL.
Definition bar_renderer.h:18
void setColor(const Colour &color)
Sets the color of the bars.
Definition bar_renderer.h:76
force_inline void setX(int index, float val)
Sets the x-position for all vertices of a specific bar.
Definition bar_renderer.h:141
force_inline void setBottom(int index, float val)
Sets the bottom y-position of a specific bar.
Definition bar_renderer.h:165
force_inline void setAdditiveBlending(bool additive_blending)
Enables or disables additive blending for the bar rendering.
Definition bar_renderer.h:251
void setScale(float scale)
Sets the scaling factor for the bars.
Definition bar_renderer.h:82
void setBarWidth(float bar_width)
Sets the relative width of each bar.
Definition bar_renderer.h:94
int num_points_
Number of bars to render.
Definition bar_renderer.h:280
virtual void render(OpenGlWrapper &open_gl, bool animate) override
Renders the bars using the current OpenGL context.
Definition bar_renderer.cpp:149
force_inline void setY(int index, float val)
Sets the top y-position of a specific bar.
Definition bar_renderer.h:154
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 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 setAuxTempoSlider(Slider *slider)
Definition delay_section.cpp:177
void render(OpenGlWrapper &open_gl, bool animate) override
Renders the bars using the current OpenGL context.
Definition delay_section.cpp:143
void setAuxFrequencySlider(Slider *slider)
Definition delay_section.cpp:178
void setAuxSyncSlider(Slider *slider)
Definition delay_section.cpp:179
void setStyleSlider(Slider *slider)
Definition delay_section.cpp:180
float getFeedback(int index)
Definition delay_section.cpp:44
void setFrequencySlider(Slider *slider)
Definition delay_section.cpp:175
DelayViewer(int num_bars, const vital::output_map &mono_modulations)
Definition delay_section.cpp:27
float getTempoFrequency(int index)
Definition delay_section.cpp:73
void setTempoSlider(Slider *slider)
Definition delay_section.cpp:174
void setActive(bool active)
Definition delay_section.cpp:182
void mouseDown(const MouseEvent &e) override
Definition delay_section.cpp:160
float getMultiplier(int index)
Definition delay_section.cpp:58
void setFeedbackSlider(Slider *slider)
Definition delay_section.cpp:172
void setSyncSlider(Slider *slider)
Definition delay_section.cpp:176
float getRawFrequency(int index)
Definition delay_section.cpp:52
void setMixSlider(Slider *slider)
Definition delay_section.cpp:173
void drawBars(OpenGlWrapper &open_gl, bool animate, int index)
Definition delay_section.cpp:92
vital::poly_float getMix()
Definition delay_section.cpp:48
void mouseDrag(const MouseEvent &e) override
Definition delay_section.cpp:164
float getFrequency(int index)
Definition delay_section.cpp:80
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
@ kWidgetMargin
Definition skin.h:103
@ kWidgetPrimaryDisabled
Definition skin.h:167
@ kWidgetPrimary2
Definition skin.h:166
@ kWidgetPrimary1
Definition skin.h:165
@ kDelay
Definition skin.h:48
Base class for all synthesizer sections, providing UI layout, painting, and interaction logic.
Definition synth_section.h:193
Rectangle< int > getDividedAreaBuffered(Rectangle< int > full_area, int num_sections, int section, int buffer)
Divides an area into equal sections with buffering, returns the specified section.
Definition synth_section.cpp:776
void drawTextComponentBackground(Graphics &g, Rectangle< int > bounds, bool extend_to_label)
Draws a background for a text component area.
Definition synth_section.cpp:319
void placeKnobsInArea(Rectangle< int > area, std::vector< Component * > knobs)
Definition synth_section.cpp:601
void addSlider(SynthSlider *slider, bool show=true, bool listen=true)
Definition synth_section.cpp:445
void drawLabel(Graphics &g, String text, Rectangle< int > component_bounds, bool text_component=false)
Draws a label text below a component.
Definition synth_section.cpp:789
void drawTempoDivider(Graphics &g, Component *sync)
Draws a divider line for tempo-related controls.
Definition synth_section.cpp:339
virtual void resized() override
Called when the component is resized. Arranges layout of child components.
Definition synth_section.cpp:35
void placeTempoControls(int x, int y, int width, int height, SynthSlider *tempo, SynthSlider *sync)
Definition synth_section.cpp:584
virtual void setActive(bool active)
Sets the active state of this section and sub-sections.
Definition synth_section.cpp:806
void drawLabelForComponent(Graphics &g, String text, Component *component, bool text_component=false)
Draws a label for a given component.
Definition synth_section.h:548
void setLabelFont(Graphics &g)
Sets the Graphics context font and color for labels.
Definition synth_section.cpp:740
void addButton(OpenGlToggleButton *button, bool show=true)
Definition synth_section.cpp:428
float findValue(Skin::ValueId value_id) const
Finds a value in the skin overrides or from the parent if not found locally.
Definition synth_section.cpp:18
virtual void paintBackground(Graphics &g)
Paints the background of the section. Calls paintContainer, heading, knobs, children.
Definition synth_section.cpp:77
float getKnobSectionHeight()
Definition synth_section.cpp:633
void setActivator(SynthButton *activator)
Definition synth_section.cpp:504
void addOpenGlComponent(OpenGlComponent *open_gl_component, bool to_beginning=false)
Definition synth_section.cpp:489
virtual void sliderValueChanged(Slider *moved_slider) override
Called when a slider value changes. Updates the synth parameter accordingly.
Definition synth_section.cpp:391
Rectangle< int > getDividedAreaUnbuffered(Rectangle< int > full_area, int num_sections, int section, int buffer)
Divides an area into equal sections without extra buffering, returns the specified section.
Definition synth_section.cpp:768
float getTitleWidth()
Definition synth_section.cpp:629
void setSkinOverride(Skin::SectionOverride skin_override)
Definition synth_section.h:303
virtual void repaintBackground()
Requests a repaint of the background.
Definition synth_section.cpp:96
static TextLookAndFeel * instance()
Singleton instance access.
Definition text_look_and_feel.h:106
@ kMono
Definition delay.h:82
@ kMidPingPong
Definition delay.h:85
@ kPingPong
Definition delay.h:84
force_inline bool enabled() const
Checks if this Processor is enabled.
Definition processor.h:310
@ kTripletMode
Definition operators.h:586
@ kFrequencyMode
Definition operators.h:583
@ kDottedMode
Definition operators.h:585
Declares the DelaySection class and related viewer classes for displaying and controlling a delay eff...
Contains faster but less accurate versions of utility math functions, such as exponential,...
const std::string kDelayStyleNames[]
Names for delay line styles (mono, stereo, ping-pong, etc.).
Definition synth_strings.h:48
force_inline poly_float equalPowerFade(poly_float t)
Produces an equal-power crossfade (sin-based) between 0.0 and 1.0.
Definition futils.h:436
force_inline poly_float clamp(poly_float value, mono_float min, mono_float max)
Clamps each lane of a vector to [min, max].
Definition poly_utils.h:306
std::map< std::string, Output * > output_map
Maps parameter names to Output pointers, representing output signals from various modules.
Definition synth_types.h:229
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
Declares the SynthSlider and related classes, providing various slider styles and functionality in th...
Declares the TempoSelector class, a specialized slider for selecting tempo-related modes.
Declares the TextSelector class and PaintPatternSelector class for selecting text-based options and d...