21 center_slider_ =
nullptr;
22 feedback_slider_ =
nullptr;
23 mix_slider_ =
nullptr;
25 mix_output_ = mono_modulations.at(
"flanger_dry_wet");
26 feedback_output_ = mono_modulations.at(
"flanger_feedback");
28 line_data_ = std::make_unique<float[]>(2 *
kResolution);
31 vertex_array_object_ = 0;
35 line_data_[2 * i] = 6.0f * t - 4.0f;
43 if (parent_ ==
nullptr)
44 parent_ = findParentComponentOfClass<SynthGuiInterface>();
51 const GLchar* varyings[] = {
"response_out" };
52 open_gl.
context.extensions.glGenVertexArrays(1, &vertex_array_object_);
53 open_gl.
context.extensions.glBindVertexArray(vertex_array_object_);
55 GLsizeiptr data_size =
static_cast<GLsizeiptr
>(
kResolution *
sizeof(float));
56 open_gl.
context.extensions.glGenBuffers(1, &line_buffer_);
57 open_gl.
context.extensions.glBindBuffer(GL_ARRAY_BUFFER, line_buffer_);
58 open_gl.
context.extensions.glBufferData(GL_ARRAY_BUFFER, 2 * data_size, line_data_.get(), GL_STATIC_DRAW);
60 open_gl.
context.extensions.glGenBuffers(1, &response_buffer_);
61 open_gl.
context.extensions.glBindBuffer(GL_ARRAY_BUFFER, response_buffer_);
62 open_gl.
context.extensions.glBufferData(GL_ARRAY_BUFFER, data_size,
nullptr, GL_STATIC_READ);
66 response_shader_.shader = shader;
69 response_shader_.position =
getAttribute(open_gl, *shader,
"position");
71 response_shader_.mix =
getUniform(open_gl, *shader,
"mix");
72 response_shader_.midi_cutoff =
getUniform(open_gl, *shader,
"midi_cutoff");
73 response_shader_.resonance =
getUniform(open_gl, *shader,
"resonance");
74 response_shader_.drive =
getUniform(open_gl, *shader,
"drive");
76 for (
int s = 0; s < FilterResponseShader::kMaxStages; ++s) {
77 String stage = String(
"stage") + String(s);
78 response_shader_.stages[s] =
getUniform(open_gl, *shader, stage.toRawUTF8());
83 drawFilterResponse(open_gl, animate);
90 open_gl.
context.extensions.glDeleteBuffers(1, &line_buffer_);
91 open_gl.
context.extensions.glDeleteBuffers(1, &response_buffer_);
93 vertex_array_object_ = 0;
97 response_shader_.shader =
nullptr;
98 response_shader_.position =
nullptr;
100 response_shader_.mix =
nullptr;
101 response_shader_.midi_cutoff =
nullptr;
102 response_shader_.resonance =
nullptr;
103 response_shader_.drive =
nullptr;
105 for (
int s = 0; s < FilterResponseShader::kMaxStages; ++s)
106 response_shader_.stages[s] =
nullptr;
112 return default_value;
115void FlangerResponse::setupFilterState() {
117 mix_ = getOutputTotal(mix_output_, mix_slider_->getValue());
118 filter_state_.
resonance_percent = getOutputTotal(feedback_output_, feedback_slider_->getValue()) * 0.5f + 0.5f;
122void FlangerResponse::loadShader(
int index) {
124 response_shader_.shader->use();
126 response_shader_.midi_cutoff->set(filter_state_.
midi_cutoff[index]);
127 response_shader_.resonance->set(
resonance);
128 response_shader_.drive->set(1.0f);
130 response_shader_.stages[0]->set(comb_filter_.
getLowAmount()[index]);
131 response_shader_.stages[1]->set(comb_filter_.
getHighAmount()[index]);
134 response_shader_.mix->set(mix_[index]);
137void FlangerResponse::bind(OpenGLContext& open_gl_context) {
138 open_gl_context.extensions.glBindVertexArray(vertex_array_object_);
139 open_gl_context.extensions.glBindBuffer(GL_ARRAY_BUFFER, line_buffer_);
141 OpenGLShaderProgram::Attribute* position = response_shader_.position.get();
142 open_gl_context.extensions.glVertexAttribPointer(position->attributeID, 2, GL_FLOAT,
143 GL_FALSE, 2 *
sizeof(
float),
nullptr);
144 open_gl_context.extensions.glEnableVertexAttribArray(position->attributeID);
146 open_gl_context.extensions.glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, response_buffer_);
149void FlangerResponse::unbind(OpenGLContext& open_gl_context) {
150 OpenGLShaderProgram::Attribute* position = response_shader_.position.get();
151 open_gl_context.extensions.glDisableVertexAttribArray(position->attributeID);
152 open_gl_context.extensions.glBindBuffer(GL_ARRAY_BUFFER, 0);
153 open_gl_context.extensions.glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, 0);
156void FlangerResponse::renderLineResponse(
OpenGlWrapper& open_gl,
int index) {
157 static constexpr float kMaxMidi = 128.0f;
159 open_gl.
context.extensions.glBeginTransformFeedback(GL_POINTS);
161 open_gl.
context.extensions.glEndTransformFeedback();
163 void* buffer = open_gl.
context.extensions.glMapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0,
166 float offset = midi[index] * (getWidth() / kMaxMidi) - getWidth() * 1.5f;
167 float* response_data = (
float*)buffer;
168 float x_adjust = getWidth() * 3.0f;
169 float y_adjust = getHeight() / 2.0f;
172 setYAt(i, y_adjust * (1.0 - response_data[i]));
175 open_gl.
context.extensions.glUnmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
178void FlangerResponse::drawFilterResponse(
OpenGlWrapper& open_gl,
bool animate) {
180 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
187 Colour color_fill_from = color_fill_to.withMultipliedAlpha(1.0f - fill_fade);
195 renderLineResponse(open_gl, 1);
209 color_fill_from = color_fill_to.withMultipliedAlpha(1.0f - fill_fade);
213 renderLineResponse(open_gl, 0);
225 static const double TEMPO_DRAG_SENSITIVITY = 0.3;
227 phase_offset_ = std::make_unique<SynthSlider>(
"flanger_phase_offset");
229 phase_offset_->setSliderStyle(Slider::RotaryHorizontalVerticalDrag);
231 mod_depth_ = std::make_unique<SynthSlider>(
"flanger_mod_depth");
233 mod_depth_->setSliderStyle(Slider::RotaryHorizontalVerticalDrag);
235 center_ = std::make_unique<SynthSlider>(
"flanger_center");
237 center_->setSliderStyle(Slider::RotaryHorizontalVerticalDrag);
240 frequency_ = std::make_unique<SynthSlider>(
"flanger_frequency");
242 frequency_->setSliderStyle(Slider::RotaryHorizontalVerticalDrag);
245 tempo_ = std::make_unique<SynthSlider>(
"flanger_tempo");
247 tempo_->setSliderStyle(Slider::RotaryHorizontalVerticalDrag);
249 tempo_->setSensitivity(TEMPO_DRAG_SENSITIVITY);
251 sync_ = std::make_unique<TempoSelector>(
"flanger_sync");
253 sync_->setSliderStyle(Slider::LinearBar);
254 sync_->setTempoSlider(tempo_.get());
255 sync_->setFreeSlider(frequency_.get());
257 feedback_ = std::make_unique<SynthSlider>(
"flanger_feedback");
259 feedback_->setSliderStyle(Slider::RotaryHorizontalVerticalDrag);
260 feedback_->setBipolar();
261 feedback_->snapToValue(
true);
263 dry_wet_ = std::make_unique<SynthSlider>(
"flanger_dry_wet");
265 dry_wet_->setSliderStyle(Slider::RotaryHorizontalVerticalDrag);
267 flanger_response_ = std::make_unique<FlangerResponse>(mono_modulations);
268 flanger_response_->setCenterSlider(center_.get());
269 flanger_response_->setFeedbackSlider(feedback_.get());
270 flanger_response_->setMixSlider(dry_wet_.get());
273 on_ = std::make_unique<SynthButton>(
"flanger_on");
284 Rectangle<int> frequency_bounds(tempo_->getX(), tempo_->getY(),
285 sync_->getRight() - tempo_->getX(), tempo_->getHeight());
290 drawLabel(g, TRANS(
"FREQUENCY"), frequency_bounds,
true);
301 Rectangle<int> bounds = getLocalBounds().withLeft(title_width);
307 int knobs_x = knobs_area.getX();
308 int knob_y2 = section_height - widget_margin;
309 int tempo_x = tempo_area.getX();
310 int tempo_width = tempo_area.getWidth();
312 int widget_x = tempo_x + tempo_width + widget_margin;
313 int widget_width = knobs_x - widget_x;
315 placeTempoControls(tempo_x, widget_margin, tempo_width, section_height - 2 * widget_margin,
316 frequency_.get(), sync_.get());
317 tempo_->setBounds(frequency_->getBounds());
318 tempo_->setModulationArea(frequency_->getModulationArea());
320 phase_offset_->setBounds(title_width + widget_margin, knob_y2, tempo_width, section_height - widget_margin);
322 flanger_response_->setBounds(widget_x, widget_margin, widget_width, getHeight() - 2 * widget_margin);
324 placeKnobsInArea(Rectangle<int>(knobs_x, 0, knobs_area.getWidth(), section_height),
325 { feedback_.get(), dry_wet_.get() });
327 placeKnobsInArea(Rectangle<int>(knobs_x, knob_y2, knobs_area.getWidth(), section_height),
328 { center_.get(), mod_depth_.get() });
334 flanger_response_->setActive(active);
void render(OpenGlWrapper &open_gl, bool animate) override
Renders the flanger response curve.
Definition flanger_section.cpp:82
virtual ~FlangerResponse()
Destructor.
Definition flanger_section.cpp:40
void init(OpenGlWrapper &open_gl) override
Initializes the OpenGL state required for rendering.
Definition flanger_section.cpp:42
static constexpr int kCombAlternatePeriod
The period used for alternating comb filtering in the displayed response.
Definition flanger_section.h:37
static constexpr int kResolution
Number of resolution points used for rendering the response.
Definition flanger_section.h:27
void destroy(OpenGlWrapper &open_gl) override
Cleans up and releases OpenGL resources.
Definition flanger_section.cpp:87
FlangerResponse(const vital::output_map &mono_modulations)
Constructs the FlangerResponse.
Definition flanger_section.cpp:13
void setActive(bool active) override
Sets the active state of the flanger section and updates the flanger response accordingly.
Definition flanger_section.cpp:333
void paintBackground(Graphics &g) override
Paints the background of the flanger section, including labels for each parameter.
Definition flanger_section.cpp:281
void resized() override
Positions and sizes the child components when the flanger section is resized.
Definition flanger_section.cpp:298
FlangerSection(String name, const vital::output_map &mono_modulations)
Constructs a FlangerSection.
Definition flanger_section.cpp:224
virtual ~FlangerSection()
Destructor.
Definition flanger_section.cpp:279
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 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
@ kCombFilterResponseVertex
Definition shaders.h:35
@ 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
@ kFlanger
Definition skin.h:52
const vital::StatusOutput * getStatusOutput(const std::string &name)
Retrieves a status output by name.
Definition synth_base.cpp:262
SynthBase * getSynth()
Returns the SynthBase instance this interface is managing.
Definition synth_gui_interface.h:85
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
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
poly_float getResonance()
Getter for the feedback parameter controlling comb/flange feedback amount.
Definition comb_filter.h:172
poly_float getHighAmount()
Getter for the high-frequency gain used in filter blending.
Definition comb_filter.h:186
void setupFilter(const FilterState &filter_state) override
Sets up the CombFilter state based on a FilterState struct.
Definition comb_filter.cpp:229
poly_float getFilterMidiCutoff()
Getter for the primary filter MIDI cutoff.
Definition comb_filter.h:193
poly_float getLowAmount()
Getter for the low-frequency gain used in filter blending.
Definition comb_filter.h:179
poly_float getFilter2MidiCutoff()
Getter for the secondary filter MIDI cutoff (used in band-spread style).
Definition comb_filter.h:200
force_inline bool enabled() const
Checks if this Processor is enabled.
Definition processor.h:310
force_inline poly_float value() const
Returns the current status value.
Definition synth_module.h:49
poly_float pass_blend
Blend parameter in [0..2], controlling pass type.
Definition synth_filter.h:117
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
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
force_inline poly_float frequencyToMidiNote(poly_float value)
Converts a frequency to a MIDI note (vectorized).
Definition poly_utils.h:130
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
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 TempoSelector class, a specialized slider for selecting tempo-related modes.