23 drive_ = mono_modulations.at(
"distortion_drive");
31 return drive_slider_->getValue();
38 float width = getWidth();
39 float height = getHeight();
40 float y_scale = height / 2.0f;
42 for (
int i = 0; i < num_points; ++i) {
43 float t = i / (num_points - 1.0f);
44 float val = 2.0f * t - 1.0f;
47 setYAt(i, (1.0f - result) * y_scale);
60 Colour color_fill_from = color_fill_to.withMultipliedAlpha(1.0f - fill_fade);
66 color_fill_from = color_fill_to.withMultipliedAlpha(1.0f - fill_fade);
80 last_mouse_position_ = e.getPosition();
84 Point<int> delta = e.getPosition() - last_mouse_position_;
85 last_mouse_position_ = e.getPosition();
87 float drive_range = drive_slider_->getMaximum() - drive_slider_->getMinimum();
88 drive_slider_->setValue(drive_slider_->getValue() - delta.y * drive_range / getWidth());
97 Point<int> last_mouse_position_;
100 Slider* type_slider_;
101 Slider* drive_slider_;
113 cutoff_slider_ =
nullptr;
114 resonance_slider_ =
nullptr;
115 blend_slider_ =
nullptr;
117 cutoff_output_ = mono_modulations.at(
"distortion_filter_cutoff");
118 resonance_output_ = mono_modulations.at(
"distortion_filter_resonance");
119 blend_output_ = mono_modulations.at(
"distortion_filter_blend");
121 line_data_ = std::make_unique<float[]>(2 *
kResolution);
123 response_buffer_ = 0;
124 vertex_array_object_ = 0;
128 line_data_[2 * i] = 2.0f * t - 1.0f;
129 line_data_[2 * i + 1] = 0.0f;
138 const GLchar* varyings[] = {
"response_out" };
139 open_gl.
context.extensions.glGenVertexArrays(1, &vertex_array_object_);
140 open_gl.
context.extensions.glBindVertexArray(vertex_array_object_);
142 GLsizeiptr data_size =
static_cast<GLsizeiptr
>(
kResolution *
sizeof(float));
143 open_gl.
context.extensions.glGenBuffers(1, &line_buffer_);
144 open_gl.
context.extensions.glBindBuffer(GL_ARRAY_BUFFER, line_buffer_);
145 open_gl.
context.extensions.glBufferData(GL_ARRAY_BUFFER, 2 * data_size, line_data_.get(), GL_STATIC_DRAW);
147 open_gl.
context.extensions.glGenBuffers(1, &response_buffer_);
148 open_gl.
context.extensions.glBindBuffer(GL_ARRAY_BUFFER, response_buffer_);
149 open_gl.
context.extensions.glBufferData(GL_ARRAY_BUFFER, data_size,
nullptr, GL_STATIC_READ);
153 response_shader_.shader = shader;
156 response_shader_.position =
getAttribute(open_gl, *shader,
"position");
158 response_shader_.mix =
getUniform(open_gl, *shader,
"mix");
159 response_shader_.midi_cutoff =
getUniform(open_gl, *shader,
"midi_cutoff");
160 response_shader_.resonance =
getUniform(open_gl, *shader,
"resonance");
161 response_shader_.drive =
getUniform(open_gl, *shader,
"drive");
162 response_shader_.db24 =
getUniform(open_gl, *shader,
"db24");
164 for (
int s = 0; s < FilterResponseShader::kMaxStages; ++s) {
165 String stage = String(
"stage") + String(s);
166 response_shader_.stages[s] =
getUniform(open_gl, *shader, stage.toRawUTF8());
171 drawFilterResponse(open_gl, animate);
178 open_gl.
context.extensions.glDeleteBuffers(1, &line_buffer_);
179 open_gl.
context.extensions.glDeleteBuffers(1, &response_buffer_);
181 vertex_array_object_ = 0;
183 response_buffer_ = 0;
185 response_shader_.shader =
nullptr;
186 response_shader_.position =
nullptr;
188 response_shader_.mix =
nullptr;
189 response_shader_.midi_cutoff =
nullptr;
190 response_shader_.resonance =
nullptr;
191 response_shader_.drive =
nullptr;
192 response_shader_.db24 =
nullptr;
194 for (
auto& stage : response_shader_.stages)
201 return default_value;
204void DistortionFilterResponse::setupFilterState() {
205 filter_state_.
midi_cutoff = getOutputTotal(cutoff_output_, cutoff_slider_->getValue());
206 filter_state_.
resonance_percent = getOutputTotal(resonance_output_, resonance_slider_->getValue());
207 filter_state_.
pass_blend = getOutputTotal(blend_output_, blend_slider_->getValue());
210void DistortionFilterResponse::loadShader(
int index) {
212 response_shader_.shader->use();
213 float min_cutoff = cutoff_slider_->getMinimum() + 0.001;
214 float cutoff = std::max(min_cutoff, filter_state_.
midi_cutoff[index]);
215 response_shader_.midi_cutoff->set(cutoff);
218 response_shader_.resonance->set(
resonance);
219 response_shader_.mix->set(1.0f);
221 response_shader_.drive->set(filter_.
getDrive()[index]);
224 response_shader_.stages[0]->set(filter_.
getLowAmount()[index]);
225 response_shader_.stages[1]->set(filter_.
getBandAmount()[index]);
226 response_shader_.stages[2]->set(filter_.
getHighAmount()[index]);
231void DistortionFilterResponse::bind(OpenGLContext& open_gl_context) {
232 open_gl_context.extensions.glBindVertexArray(vertex_array_object_);
233 open_gl_context.extensions.glBindBuffer(GL_ARRAY_BUFFER, line_buffer_);
235 OpenGLShaderProgram::Attribute* position = response_shader_.position.get();
236 open_gl_context.extensions.glVertexAttribPointer(position->attributeID, 2, GL_FLOAT,
237 GL_FALSE, 2 *
sizeof(
float),
nullptr);
238 open_gl_context.extensions.glEnableVertexAttribArray(position->attributeID);
240 open_gl_context.extensions.glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, response_buffer_);
243void DistortionFilterResponse::unbind(OpenGLContext& open_gl_context) {
244 OpenGLShaderProgram::Attribute* position = response_shader_.position.get();
245 open_gl_context.extensions.glDisableVertexAttribArray(position->attributeID);
246 open_gl_context.extensions.glBindBuffer(GL_ARRAY_BUFFER, 0);
247 open_gl_context.extensions.glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, 0);
250void DistortionFilterResponse::renderLineResponse(
OpenGlWrapper& open_gl) {
251 open_gl.
context.extensions.glBeginTransformFeedback(GL_POINTS);
253 open_gl.
context.extensions.glEndTransformFeedback();
255 void* buffer = open_gl.
context.extensions.glMapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0,
258 float* response_data = (
float*)buffer;
259 float x_adjust = getWidth();
260 float y_adjust = getHeight() / 2.0f;
263 setYAt(i, y_adjust * (1.0 - response_data[i]));
266 open_gl.
context.extensions.glUnmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
269void DistortionFilterResponse::drawFilterResponse(
OpenGlWrapper& open_gl,
bool animate) {
271 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
278 Colour color_fill_from = color_fill_to.withMultipliedAlpha(1.0f - fill_fade);
285 renderLineResponse(open_gl);
299 color_fill_from = color_fill_to.withMultipliedAlpha(1.0f - fill_fade);
303 renderLineResponse(open_gl);
315 type_ = std::make_unique<TextSelector>(
"distortion_type");
317 type_->setSliderStyle(Slider::RotaryHorizontalVerticalDrag);
321 filter_order_ = std::make_unique<TextSelector>(
"distortion_filter_order");
323 filter_order_->setSliderStyle(Slider::RotaryHorizontalVerticalDrag);
327 filter_cutoff_ = std::make_unique<SynthSlider>(
"distortion_filter_cutoff");
329 filter_cutoff_->setSliderStyle(Slider::RotaryHorizontalVerticalDrag);
332 filter_resonance_ = std::make_unique<SynthSlider>(
"distortion_filter_resonance");
334 filter_resonance_->setSliderStyle(Slider::RotaryHorizontalVerticalDrag);
336 filter_blend_ = std::make_unique<SynthSlider>(
"distortion_filter_blend");
338 filter_blend_->setSliderStyle(Slider::RotaryHorizontalVerticalDrag);
339 filter_blend_->setBipolar();
342 distortion_viewer_ = std::make_unique<DistortionViewer>(resolution, mono_modulations);
344 distortion_viewer_->setTypeSlider(type_.get());
346 drive_ = std::make_unique<SynthSlider>(
"distortion_drive");
348 drive_->setSliderStyle(Slider::RotaryHorizontalVerticalDrag);
349 distortion_viewer_->setDriveSlider(drive_.get());
351 mix_ = std::make_unique<SynthSlider>(
"distortion_mix");
353 mix_->setSliderStyle(Slider::RotaryHorizontalVerticalDrag);
355 filter_response_ = std::make_unique<DistortionFilterResponse>(mono_modulations);
357 filter_response_->setCutoffSlider(filter_cutoff_.get());
358 filter_response_->setResonanceSlider(filter_resonance_.get());
359 filter_response_->setBlendSlider(filter_blend_.get());
361 on_ = std::make_unique<SynthButton>(
"distortion_on");
389 Rectangle<int> bounds = getLocalBounds().withLeft(title_width);
393 int widget_x = settings_area.getRight() + widget_margin;
394 int widget_width = knobs_area.getX() - widget_x;
396 int knob_y2 = section_height - widget_margin;
397 type_->setBounds(settings_area.getX(), widget_margin, settings_area.getWidth(), section_height - 2 * widget_margin);
398 filter_order_->setBounds(settings_area.getX(), knob_y2 + widget_margin,
399 settings_area.getWidth(), section_height - 2 * widget_margin);
401 int distortion_viewer_height = (getHeight() - 3 * widget_margin) / 2;
402 distortion_viewer_->setBounds(widget_x, widget_margin, widget_width, distortion_viewer_height);
404 int response_height = getHeight() - distortion_viewer_height - 3 * widget_margin;
405 int filter_y = getHeight() - response_height - widget_margin;
406 filter_response_->setBounds(widget_x, filter_y, widget_width, response_height);
408 placeKnobsInArea(Rectangle<int>(knobs_area.getX(), 0, knobs_area.getWidth(), section_height),
409 { drive_.get(), mix_.get() });
411 placeKnobsInArea(Rectangle<int>(knobs_area.getX(), knob_y2, knobs_area.getWidth(), section_height),
412 { filter_cutoff_.get(), filter_resonance_.get(), filter_blend_.get() });
420 distortion_viewer_->setActive(active);
425 if (changed_slider == filter_order_.get())
437 filter_response_->setActive(active);
438 filter_cutoff_->setActive(active);
439 filter_resonance_->setActive(active);
440 filter_blend_->setActive(active);
void render(OpenGlWrapper &open_gl, bool animate) override
Definition distortion_section.cpp:170
virtual ~DistortionFilterResponse()
void destroy(OpenGlWrapper &open_gl) override
Definition distortion_section.cpp:175
void init(OpenGlWrapper &open_gl) override
Definition distortion_section.cpp:135
static constexpr int kResolution
Resolution of the filter response line.
Definition distortion_section.h:25
DistortionFilterResponse(const vital::output_map &mono_modulations)
Definition distortion_section.cpp:104
virtual ~DistortionSection()
Destructor.
void setActive(bool active) override
Definition distortion_section.cpp:418
void sliderValueChanged(Slider *changed_slider) override
Definition distortion_section.cpp:424
static constexpr int kViewerResolution
Resolution for visualizing distortion line.
Definition distortion_section.h:151
void paintBackground(Graphics &g) override
Definition distortion_section.cpp:369
void setAllValues(vital::control_map &controls) override
Definition distortion_section.cpp:431
void resized() override
Resizes and lays out child components.
Definition distortion_section.cpp:384
DistortionSection(String name, const vital::output_map &mono_modulations)
Definition distortion_section.cpp:314
void setFilterActive(bool active)
Definition distortion_section.cpp:436
Definition distortion_section.cpp:17
static constexpr float kDrawPercent
Definition distortion_section.cpp:19
void mouseDrag(const MouseEvent &e) override
Definition distortion_section.cpp:83
void drawDistortion(OpenGlWrapper &open_gl, bool animate, int index)
Definition distortion_section.cpp:35
vital::poly_float getDrive()
Definition distortion_section.cpp:29
void setDriveSlider(Slider *slider)
Definition distortion_section.cpp:92
void render(OpenGlWrapper &open_gl, bool animate) override
Renders the line using OpenGL.
Definition distortion_section.cpp:53
void setActive(bool active)
Definition distortion_section.cpp:93
DistortionViewer(int resolution, const vital::output_map &mono_modulations)
Definition distortion_section.cpp:21
void mouseDown(const MouseEvent &e) override
Definition distortion_section.cpp:79
void setTypeSlider(Slider *slider)
Definition distortion_section.cpp:91
static bool setViewPort(Component *component, Rectangle< int > bounds, OpenGlWrapper &open_gl)
Sets the OpenGL viewport to match a specified rectangle within a component.
Definition open_gl_component.cpp:42
static std::unique_ptr< OpenGLShaderProgram::Attribute > getAttribute(const OpenGlWrapper &open_gl, const OpenGLShaderProgram &program, const char *name)
Retrieves an attribute from the shader program if it exists.
Definition open_gl_component.h:79
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
force_inline void checkGlError()
Checks for and asserts that there are no OpenGL errors.
Definition open_gl_component.h:231
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
static std::unique_ptr< OpenGLShaderProgram::Uniform > getUniform(const OpenGlWrapper &open_gl, const OpenGLShaderProgram &program, const char *name)
Retrieves a uniform from the shader program if it exists.
Definition open_gl_component.h:64
A component for rendering lines with optional filling and boost effects using OpenGL.
Definition open_gl_line_renderer.h:16
virtual void init(OpenGlWrapper &open_gl) override
Initializes OpenGL resources for rendering the line.
Definition open_gl_line_renderer.cpp:78
virtual void destroy(OpenGlWrapper &open_gl) override
Destroys OpenGL resources allocated by this line renderer.
Definition open_gl_line_renderer.cpp:468
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 setFillColor(Colour fill_color)
Sets a uniform fill color if only one color is needed.
Definition open_gl_line_renderer.h:127
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
@ kDigitalFilterResponseVertex
Definition shaders.h:38
@ kColorFragment
Definition shaders.h:63
OpenGLShaderProgram * getShaderProgram(VertexShader vertex_shader, FragmentShader fragment_shader, const GLchar **varyings=nullptr)
Retrieves or creates an OpenGLShaderProgram from a given vertex and fragment shader pair.
Definition shaders.cpp:953
@ kWidgetMargin
Definition skin.h:103
@ 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
@ kDistortion
Definition skin.h:49
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
virtual void resized() override
Called when the component is resized. Arranges layout of child components.
Definition synth_section.cpp:35
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
bool isActive() const
Checks if the section is currently active.
Definition synth_section.h:683
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
virtual void setAllValues(vital::control_map &controls)
Sets values for all known parameters from a control map.
Definition synth_section.cpp:827
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
void setSliderHasHzAlternateDisplay(SynthSlider *slider)
Definition synth_section.cpp:410
float getTitleWidth()
Definition synth_section.cpp:629
void setSkinOverride(Skin::SectionOverride skin_override)
Definition synth_section.h:303
static TextLookAndFeel * instance()
Singleton instance access.
Definition text_look_and_feel.h:106
void setDriveCompensation(bool drive_compensation)
Enables or disables drive compensation (reducing drive as resonance increases).
Definition digital_svf.h:407
poly_float getResonance() const
Retrieves the current resonance value (inverted if needed).
Definition digital_svf.h:351
void setupFilter(const FilterState &filter_state) override
Configures this SVF based on a FilterState (cutoff, resonance, style, etc.).
Definition digital_svf.cpp:237
poly_float getBandAmount() const
Retrieves the current band-frequency mix portion.
Definition digital_svf.h:363
poly_float getHighAmount24(int style) const
Helper for a 24 dB filter style that may swap low/high in a dual notch band.
Definition digital_svf.h:389
poly_float getLowAmount24(int style) const
Helper for a 24 dB filter style that may swap low/high in a dual notch band.
Definition digital_svf.h:377
poly_float getHighAmount() const
Retrieves the current high-frequency mix portion.
Definition digital_svf.h:369
poly_float getLowAmount() const
Retrieves the current low-frequency mix portion.
Definition digital_svf.h:357
poly_float getDrive() const
Retrieves the final drive (post drive compensation) used in the filter.
Definition digital_svf.h:339
static poly_float getDriveValue(int type, poly_float input_drive)
Converts an input drive in dB to a linear multiplier depending on distortion type.
Definition distortion.h:121
static poly_float getDrivenValue(int type, poly_float value, poly_float drive)
Applies the specified distortion to a single sample given the drive multiplier.
Definition distortion.cpp:135
force_inline bool enabled() const
Checks if this Processor is enabled.
Definition processor.h:310
poly_float pass_blend
Blend parameter in [0..2], controlling pass type.
Definition synth_filter.h:117
int style
Filter style enum (e.g., k12Db, k24Db)
Definition synth_filter.h:116
poly_float midi_cutoff
MIDI note-based cutoff value.
Definition synth_filter.h:110
poly_float resonance_percent
Resonance parameter in [0..1].
Definition synth_filter.h:112
@ k12Db
Definition synth_filter.h:75
Declares the DistortionSection class and related components for displaying and controlling a distorti...
const std::string kDistortionFilterOrderNames[]
Filter order names for distortion section (pre, post, none).
Definition synth_strings.h:187
const std::string kDistortionTypeNames[]
More descriptive names for various distortion types.
Definition synth_strings.h:174
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
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
OpenGLContext & context
The OpenGLContext for current rendering.
Definition shaders.h:181
Shaders * shaders
Pointer to the Shaders instance providing compiled shaders.
Definition shaders.h:182
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 TabSelector class, a slider-based UI component for selecting tabs.
Declares the TextSelector class and PaintPatternSelector class for selecting text-based options and d...