22 cutoff_slider_ =
nullptr;
23 resonance_slider_ =
nullptr;
24 blend_slider_ =
nullptr;
25 mix_slider_ =
nullptr;
27 line_data_ = std::make_unique<float[]>(2 *
kResolution);
30 vertex_array_object_ = 0;
34 line_data_[2 * i] = 2.0f * t - 1.0f;
35 line_data_[2 * i + 1] = 0.0f;
38 filter_mix_output_ = mono_modulations.at(
"phaser_dry_wet");
39 resonance_output_ = mono_modulations.at(
"phaser_feedback");
40 blend_output_ = mono_modulations.at(
"phaser_blend");
42 blend_setting_ = 1.0f;
50 if (parent_ ==
nullptr)
51 parent_ = findParentComponentOfClass<SynthGuiInterface>();
58 const GLchar* varyings[] = {
"response_out" };
59 open_gl.
context.extensions.glGenVertexArrays(1, &vertex_array_object_);
60 open_gl.
context.extensions.glBindVertexArray(vertex_array_object_);
62 GLsizeiptr data_size =
static_cast<GLsizeiptr
>(
kResolution *
sizeof(float));
63 open_gl.
context.extensions.glGenBuffers(1, &line_buffer_);
64 open_gl.
context.extensions.glBindBuffer(GL_ARRAY_BUFFER, line_buffer_);
65 open_gl.
context.extensions.glBufferData(GL_ARRAY_BUFFER, 2 * data_size, line_data_.get(), GL_STATIC_DRAW);
67 open_gl.
context.extensions.glGenBuffers(1, &response_buffer_);
68 open_gl.
context.extensions.glBindBuffer(GL_ARRAY_BUFFER, response_buffer_);
69 open_gl.
context.extensions.glBufferData(GL_ARRAY_BUFFER, data_size,
nullptr, GL_STATIC_READ);
73 response_shader_.shader = shader;
76 response_shader_.position =
getAttribute(open_gl, *shader,
"position");
78 response_shader_.mix =
getUniform(open_gl, *shader,
"mix");
79 response_shader_.midi_cutoff =
getUniform(open_gl, *shader,
"midi_cutoff");
80 response_shader_.resonance =
getUniform(open_gl, *shader,
"resonance");
81 response_shader_.db24 =
getUniform(open_gl, *shader,
"db24");
83 for (
int s = 0; s < FilterResponseShader::kMaxStages; ++s) {
84 String stage = String(
"stage") + String(s);
85 response_shader_.stages[s] =
getUniform(open_gl, *shader, stage.toRawUTF8());
90 drawFilterResponse(open_gl, animate);
97 open_gl.
context.extensions.glDeleteBuffers(1, &line_buffer_);
98 open_gl.
context.extensions.glDeleteBuffers(1, &response_buffer_);
100 vertex_array_object_ = 0;
102 response_buffer_ = 0;
104 response_shader_.shader =
nullptr;
105 response_shader_.position =
nullptr;
107 response_shader_.mix =
nullptr;
108 response_shader_.midi_cutoff =
nullptr;
109 response_shader_.resonance =
nullptr;
110 response_shader_.db24 =
nullptr;
112 for (
int s = 0; s < FilterResponseShader::kMaxStages; ++s)
113 response_shader_.stages[s] =
nullptr;
119 return default_value;
122void PhaserResponse::setupFilterState() {
124 mix_ = getOutputTotal(filter_mix_output_, mix_slider_->getValue());
125 filter_state_.
resonance_percent = getOutputTotal(resonance_output_, resonance_slider_->getValue());
126 filter_state_.
pass_blend = getOutputTotal(blend_output_, blend_slider_->getValue());
129void PhaserResponse::loadShader(
int index) {
131 response_shader_.shader->use();
132 response_shader_.midi_cutoff->set(filter_state_.
midi_cutoff[index]);
133 response_shader_.resonance->set(phaser_filter_.
getResonance()[index]);
136 response_shader_.stages[0]->set(phaser_filter_.
getPeak1Amount()[index]);
137 response_shader_.stages[1]->set(phaser_filter_.
getPeak3Amount()[index]);
138 response_shader_.stages[2]->set(phaser_filter_.
getPeak5Amount()[index]);
139 response_shader_.mix->set(mix_[index]);
142void PhaserResponse::bind(OpenGLContext& open_gl_context) {
143 open_gl_context.extensions.glBindVertexArray(vertex_array_object_);
144 open_gl_context.extensions.glBindBuffer(GL_ARRAY_BUFFER, line_buffer_);
146 OpenGLShaderProgram::Attribute* position = response_shader_.position.get();
147 open_gl_context.extensions.glVertexAttribPointer(position->attributeID, 2, GL_FLOAT,
148 GL_FALSE, 2 *
sizeof(
float),
nullptr);
149 open_gl_context.extensions.glEnableVertexAttribArray(position->attributeID);
151 open_gl_context.extensions.glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, response_buffer_);
154void PhaserResponse::unbind(OpenGLContext& open_gl_context) {
155 OpenGLShaderProgram::Attribute* position = response_shader_.position.get();
156 open_gl_context.extensions.glDisableVertexAttribArray(position->attributeID);
157 open_gl_context.extensions.glBindBuffer(GL_ARRAY_BUFFER, 0);
158 open_gl_context.extensions.glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, 0);
161void PhaserResponse::renderLineResponse(
OpenGlWrapper& open_gl) {
162 open_gl.
context.extensions.glBeginTransformFeedback(GL_POINTS);
164 open_gl.
context.extensions.glEndTransformFeedback();
166 void* buffer = open_gl.
context.extensions.glMapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0,
169 float* response_data = (
float*)buffer;
170 float x_adjust = getWidth();
171 float y_adjust = getHeight() / 2.0f;
174 setYAt(i, y_adjust * (1.0 - response_data[i]));
177 open_gl.
context.extensions.glUnmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
180void PhaserResponse::drawFilterResponse(
OpenGlWrapper& open_gl,
bool animate) {
182 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
189 Colour color_fill_from = color_fill_to.withMultipliedAlpha(1.0f - fill_fade);
197 renderLineResponse(open_gl);
211 color_fill_from = color_fill_to.withMultipliedAlpha(1.0f - fill_fade);
215 renderLineResponse(open_gl);
227 static const double TEMPO_DRAG_SENSITIVITY = 0.3;
229 phase_offset_ = std::make_unique<SynthSlider>(
"phaser_phase_offset");
231 phase_offset_->setSliderStyle(Slider::RotaryHorizontalVerticalDrag);
233 mod_depth_ = std::make_unique<SynthSlider>(
"phaser_mod_depth");
235 mod_depth_->setSliderStyle(Slider::RotaryHorizontalVerticalDrag);
237 center_ = std::make_unique<SynthSlider>(
"phaser_center");
239 center_->setSliderStyle(Slider::RotaryHorizontalVerticalDrag);
242 frequency_ = std::make_unique<SynthSlider>(
"phaser_frequency");
244 frequency_->setSliderStyle(Slider::RotaryHorizontalVerticalDrag);
247 tempo_ = std::make_unique<SynthSlider>(
"phaser_tempo");
249 tempo_->setSliderStyle(Slider::RotaryHorizontalVerticalDrag);
251 tempo_->setSensitivity(TEMPO_DRAG_SENSITIVITY);
253 sync_ = std::make_unique<TempoSelector>(
"phaser_sync");
255 sync_->setSliderStyle(Slider::LinearBar);
256 sync_->setTempoSlider(tempo_.get());
257 sync_->setFreeSlider(frequency_.get());
259 feedback_ = std::make_unique<SynthSlider>(
"phaser_feedback");
261 feedback_->setSliderStyle(Slider::RotaryHorizontalVerticalDrag);
263 blend_ = std::make_unique<SynthSlider>(
"phaser_blend");
265 blend_->setSliderStyle(Slider::LinearBar);
266 blend_->snapToValue(
true, 1.0);
267 blend_->setBipolar();
268 blend_->setPopupPlacement(BubbleComponent::above);
270 dry_wet_ = std::make_unique<SynthSlider>(
"phaser_dry_wet");
272 dry_wet_->setSliderStyle(Slider::RotaryHorizontalVerticalDrag);
274 phaser_response_ = std::make_unique<PhaserResponse>(mono_modulations);
275 phaser_response_->setCutoffSlider(center_.get());
276 phaser_response_->setResonanceSlider(feedback_.get());
277 phaser_response_->setBlendSlider(blend_.get());
278 phaser_response_->setMixSlider(dry_wet_.get());
281 on_ = std::make_unique<SynthButton>(
"phaser_on");
292 Rectangle<int> frequency_bounds(tempo_->getX(), tempo_->getY(),
293 sync_->getRight() - tempo_->getX(), tempo_->getHeight());
298 drawLabel(g, TRANS(
"FREQUENCY"), frequency_bounds,
true);
309 Rectangle<int> bounds = getLocalBounds().withLeft(title_width);
315 int knobs_x = knobs_area.getX();
316 int knob_y2 = section_height - widget_margin;
317 int tempo_x = tempo_area.getX();
318 int tempo_width = tempo_area.getWidth();
320 int widget_x = tempo_x + tempo_width + widget_margin;
321 int widget_width = knobs_x - widget_x;
323 placeTempoControls(tempo_x, widget_margin, tempo_width, section_height - 2 * widget_margin,
324 frequency_.get(), sync_.get());
325 tempo_->setBounds(frequency_->getBounds());
326 tempo_->setModulationArea(frequency_->getModulationArea());
328 phase_offset_->setBounds(title_width + widget_margin, knob_y2, tempo_width, section_height - widget_margin);
330 blend_->setBounds(widget_x - widget_margin, widget_margin -
getSliderOverlap(),
333 phaser_response_->setBounds(widget_x, widget_y, widget_width, getHeight() - widget_y - widget_margin);
335 placeKnobsInArea(Rectangle<int>(knobs_x, 0, knobs_area.getWidth(), section_height),
336 { feedback_.get(), dry_wet_.get() });
338 placeKnobsInArea(Rectangle<int>(knobs_x, knob_y2, knobs_area.getWidth(), section_height),
339 { center_.get(), mod_depth_.get() });
346 phaser_response_->setActive(active);
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
void init(OpenGlWrapper &open_gl) override
Initializes the OpenGL context and shaders for rendering the phaser response.
Definition phaser_section.cpp:49
virtual ~PhaserResponse()
Destructor.
Definition phaser_section.cpp:47
PhaserResponse(const vital::output_map &mono_modulations)
Constructs a PhaserResponse object.
Definition phaser_section.cpp:13
void destroy(OpenGlWrapper &open_gl) override
Cleans up the OpenGL resources used by this class.
Definition phaser_section.cpp:94
static constexpr int kDefaultVisualSampleRate
The default visual sample rate used for filter calculations.
Definition phaser_section.h:27
static constexpr int kResolution
The resolution of the frequency response drawing.
Definition phaser_section.h:25
void render(OpenGlWrapper &open_gl, bool animate) override
Renders the phaser response curve.
Definition phaser_section.cpp:89
void resized() override
Called when the component is resized.
Definition phaser_section.cpp:306
PhaserSection(String name, const vital::output_map &mono_modulations)
Constructs a PhaserSection.
Definition phaser_section.cpp:226
virtual ~PhaserSection()
Destructor.
Definition phaser_section.cpp:287
void setActive(bool active) override
Sets the active state of the phaser section.
Definition phaser_section.cpp:344
void paintBackground(Graphics &g) override
Paints the background of the phaser section, including labels and backgrounds.
Definition phaser_section.cpp:289
@ kPhaserFilterResponseVertex
Definition shaders.h:43
@ 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
@ kPhaser
Definition skin.h:53
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
float getSliderWidth()
Definition synth_section.cpp:637
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
float getSliderOverlap()
Definition synth_section.cpp:641
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
float getSliderOverlapWithSpace()
Definition synth_section.cpp:648
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 getPeak1Amount()
Gets the current peak1 (lowest peak cluster) mix amount.
Definition phaser_filter.h:120
poly_float getResonance()
Gets the current resonance value.
Definition phaser_filter.h:108
poly_float getPeak3Amount()
Gets the current peak3 (second peak cluster) mix amount.
Definition phaser_filter.h:126
poly_float getPeak5Amount()
Gets the current peak5 (highest peak cluster) mix amount.
Definition phaser_filter.h:132
void setupFilter(const FilterState &filter_state) override
Sets up the filter parameters (resonance, drive, peaks) based on the FilterState.
Definition phaser_filter.cpp:71
force_inline bool enabled() const
Checks if this Processor is enabled.
Definition processor.h:310
virtual void setSampleRate(int sample_rate)
Updates the sample rate of this Processor (scaled by oversampling).
Definition processor.h:285
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
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
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.