Vital
Loading...
Searching...
No Matches
flanger_section.cpp
Go to the documentation of this file.
1#include "flanger_section.h"
2
3#include "skin.h"
4#include "fonts.h"
5#include "shaders.h"
6#include "synth_strings.h"
7#include "synth_button.h"
9#include "synth_slider.h"
10#include "tempo_selector.h"
11#include "text_look_and_feel.h"
12
14 parent_ = nullptr;
15 active_ = true;
16 mix_ = 1.0f;
17
18 setFill(true);
19 setFillCenter(-1.0f);
20
21 center_slider_ = nullptr;
22 feedback_slider_ = nullptr;
23 mix_slider_ = nullptr;
24
25 mix_output_ = mono_modulations.at("flanger_dry_wet");
26 feedback_output_ = mono_modulations.at("flanger_feedback");
27
28 line_data_ = std::make_unique<float[]>(2 * kResolution);
29 line_buffer_ = 0;
30 response_buffer_ = 0;
31 vertex_array_object_ = 0;
32
33 for (int i = 0; i < kResolution; ++i) {
34 float t = i / (kResolution - 1.0f);
35 line_data_[2 * i] = 6.0f * t - 4.0f;
36 line_data_[2 * i + 1] = (i / kCombAlternatePeriod) % 2;
37 }
38}
39
41
43 if (parent_ == nullptr)
44 parent_ = findParentComponentOfClass<SynthGuiInterface>();
45
46 if (parent_)
47 flanger_frequency_ = parent_->getSynth()->getStatusOutput("flanger_delay_frequency");
48
50
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_);
54
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);
59
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);
63
64 OpenGLShaderProgram* shader = open_gl.shaders->getShaderProgram(Shaders::kCombFilterResponseVertex,
65 Shaders::kColorFragment, varyings);
66 response_shader_.shader = shader;
67
68 shader->use();
69 response_shader_.position = getAttribute(open_gl, *shader, "position");
70
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");
75
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());
79 }
80}
81
82void FlangerResponse::render(OpenGlWrapper& open_gl, bool animate) {
83 drawFilterResponse(open_gl, animate);
84 renderCorners(open_gl, animate);
85}
86
89
90 open_gl.context.extensions.glDeleteBuffers(1, &line_buffer_);
91 open_gl.context.extensions.glDeleteBuffers(1, &response_buffer_);
92
93 vertex_array_object_ = 0;
94 line_buffer_ = 0;
95 response_buffer_ = 0;
96
97 response_shader_.shader = nullptr;
98 response_shader_.position = nullptr;
99
100 response_shader_.mix = nullptr;
101 response_shader_.midi_cutoff = nullptr;
102 response_shader_.resonance = nullptr;
103 response_shader_.drive = nullptr;
104
105 for (int s = 0; s < FilterResponseShader::kMaxStages; ++s)
106 response_shader_.stages[s] = nullptr;
107}
108
109vital::poly_float FlangerResponse::getOutputTotal(vital::Output* output, vital::poly_float default_value) {
110 if (output && output->owner->enabled())
111 return output->trigger_value;
112 return default_value;
113}
114
115void FlangerResponse::setupFilterState() {
116 filter_state_.midi_cutoff = 0.0f;
117 mix_ = getOutputTotal(mix_output_, mix_slider_->getValue());
118 filter_state_.resonance_percent = getOutputTotal(feedback_output_, feedback_slider_->getValue()) * 0.5f + 0.5f;
119 filter_state_.pass_blend = 1.0f;
120}
121
122void FlangerResponse::loadShader(int index) {
123 comb_filter_.setupFilter(filter_state_);
124 response_shader_.shader->use();
125 float resonance = vital::utils::clamp(comb_filter_.getResonance()[index], -0.99f, 0.99f);
126 response_shader_.midi_cutoff->set(filter_state_.midi_cutoff[index]);
127 response_shader_.resonance->set(resonance);
128 response_shader_.drive->set(1.0f);
129
130 response_shader_.stages[0]->set(comb_filter_.getLowAmount()[index]);
131 response_shader_.stages[1]->set(comb_filter_.getHighAmount()[index]);
132 response_shader_.stages[2]->set(comb_filter_.getFilterMidiCutoff()[index]);
133 response_shader_.stages[3]->set(comb_filter_.getFilter2MidiCutoff()[index]);
134 response_shader_.mix->set(mix_[index]);
135}
136
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_);
140
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);
145
146 open_gl_context.extensions.glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, response_buffer_);
147}
148
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);
154}
155
156void FlangerResponse::renderLineResponse(OpenGlWrapper& open_gl, int index) {
157 static constexpr float kMaxMidi = 128.0f;
158
159 open_gl.context.extensions.glBeginTransformFeedback(GL_POINTS);
160 glDrawArrays(GL_POINTS, 0, kResolution);
161 open_gl.context.extensions.glEndTransformFeedback();
162
163 void* buffer = open_gl.context.extensions.glMapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0,
164 kResolution * sizeof(float), GL_MAP_READ_BIT);
165 vital::poly_float midi = vital::utils::frequencyToMidiNote(flanger_frequency_->value());
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;
170 for (int i = 0; i < kResolution; ++i) {
171 setXAt(i, x_adjust * i / (kResolution - 1.0f) + offset);
172 setYAt(i, y_adjust * (1.0 - response_data[i]));
173 }
174
175 open_gl.context.extensions.glUnmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
176}
177
178void FlangerResponse::drawFilterResponse(OpenGlWrapper& open_gl, bool animate) {
179 setupFilterState();
180 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
181 glEnable(GL_BLEND);
182 setViewPort(open_gl);
183
184 Colour color_line = findColour(Skin::kWidgetPrimary2, true);
185 Colour color_fill_to = findColour(Skin::kWidgetSecondary2, true);
186 float fill_fade = findValue(Skin::kWidgetFillFade);
187 Colour color_fill_from = color_fill_to.withMultipliedAlpha(1.0f - fill_fade);
188
191
192 if (active_) {
193 bind(open_gl.context);
194 loadShader(1);
195 renderLineResponse(open_gl, 1);
196
197 setFillColors(color_fill_from, color_fill_to);
198 setColor(color_line);
199 OpenGlLineRenderer::render(open_gl, animate);
200 }
201
202 glEnable(GL_BLEND);
203 color_line = findColour(Skin::kWidgetPrimary1, true);
204 color_fill_to = findColour(Skin::kWidgetSecondary1, true);
205 if (!active_) {
206 color_line = findColour(Skin::kWidgetPrimaryDisabled, true);
207 color_fill_to = findColour(Skin::kWidgetSecondaryDisabled, true);
208 }
209 color_fill_from = color_fill_to.withMultipliedAlpha(1.0f - fill_fade);
210
211 bind(open_gl.context);
212 loadShader(0);
213 renderLineResponse(open_gl, 0);
214
215 setFillColors(color_fill_from, color_fill_to);
216 setColor(color_line);
217 OpenGlLineRenderer::render(open_gl, animate);
218
219 unbind(open_gl.context);
220 glDisable(GL_BLEND);
221 checkGlError();
222}
223
224FlangerSection::FlangerSection(String name, const vital::output_map& mono_modulations) : SynthSection(name) {
225 static const double TEMPO_DRAG_SENSITIVITY = 0.3;
226
227 phase_offset_ = std::make_unique<SynthSlider>("flanger_phase_offset");
228 addSlider(phase_offset_.get());
229 phase_offset_->setSliderStyle(Slider::RotaryHorizontalVerticalDrag);
230
231 mod_depth_ = std::make_unique<SynthSlider>("flanger_mod_depth");
232 addSlider(mod_depth_.get());
233 mod_depth_->setSliderStyle(Slider::RotaryHorizontalVerticalDrag);
234
235 center_ = std::make_unique<SynthSlider>("flanger_center");
236 addSlider(center_.get());
237 center_->setSliderStyle(Slider::RotaryHorizontalVerticalDrag);
238 setSliderHasHzAlternateDisplay(center_.get());
239
240 frequency_ = std::make_unique<SynthSlider>("flanger_frequency");
241 addSlider(frequency_.get());
242 frequency_->setSliderStyle(Slider::RotaryHorizontalVerticalDrag);
243 frequency_->setLookAndFeel(TextLookAndFeel::instance());
244
245 tempo_ = std::make_unique<SynthSlider>("flanger_tempo");
246 addSlider(tempo_.get());
247 tempo_->setSliderStyle(Slider::RotaryHorizontalVerticalDrag);
248 tempo_->setLookAndFeel(TextLookAndFeel::instance());
249 tempo_->setSensitivity(TEMPO_DRAG_SENSITIVITY);
250
251 sync_ = std::make_unique<TempoSelector>("flanger_sync");
252 addSlider(sync_.get());
253 sync_->setSliderStyle(Slider::LinearBar);
254 sync_->setTempoSlider(tempo_.get());
255 sync_->setFreeSlider(frequency_.get());
256
257 feedback_ = std::make_unique<SynthSlider>("flanger_feedback");
258 addSlider(feedback_.get());
259 feedback_->setSliderStyle(Slider::RotaryHorizontalVerticalDrag);
260 feedback_->setBipolar();
261 feedback_->snapToValue(true);
262
263 dry_wet_ = std::make_unique<SynthSlider>("flanger_dry_wet");
264 addSlider(dry_wet_.get());
265 dry_wet_->setSliderStyle(Slider::RotaryHorizontalVerticalDrag);
266
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());
271 addOpenGlComponent(flanger_response_.get());
272
273 on_ = std::make_unique<SynthButton>("flanger_on");
274 addButton(on_.get());
275 setActivator(on_.get());
277}
278
280
283
284 Rectangle<int> frequency_bounds(tempo_->getX(), tempo_->getY(),
285 sync_->getRight() - tempo_->getX(), tempo_->getHeight());
286 drawTextComponentBackground(g, frequency_bounds, true);
287 drawTempoDivider(g, sync_.get());
288
289 setLabelFont(g);
290 drawLabel(g, TRANS("FREQUENCY"), frequency_bounds, true);
291 drawLabelForComponent(g, TRANS("FEEDBACK"), feedback_.get());
292 drawLabelForComponent(g, TRANS("MIX"), dry_wet_.get());
293 drawLabelForComponent(g, TRANS("CENTER"), center_.get());
294 drawLabelForComponent(g, TRANS("DEPTH"), mod_depth_.get());
295 drawLabelForComponent(g, TRANS("OFFSET"), phase_offset_.get());
296}
297
299 int title_width = getTitleWidth();
300 int widget_margin = findValue(Skin::kWidgetMargin);
301 Rectangle<int> bounds = getLocalBounds().withLeft(title_width);
302 Rectangle<int> knobs_area = getDividedAreaBuffered(bounds, 3, 2, widget_margin);
303 Rectangle<int> tempo_area = getDividedAreaUnbuffered(bounds, 4, 0, widget_margin);
304
305 int section_height = getKnobSectionHeight();
306
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();
311
312 int widget_x = tempo_x + tempo_width + widget_margin;
313 int widget_width = knobs_x - widget_x;
314
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());
319
320 phase_offset_->setBounds(title_width + widget_margin, knob_y2, tempo_width, section_height - widget_margin);
321
322 flanger_response_->setBounds(widget_x, widget_margin, widget_width, getHeight() - 2 * widget_margin);
323
324 placeKnobsInArea(Rectangle<int>(knobs_x, 0, knobs_area.getWidth(), section_height),
325 { feedback_.get(), dry_wet_.get() });
326
327 placeKnobsInArea(Rectangle<int>(knobs_x, knob_y2, knobs_area.getWidth(), section_height),
328 { center_.get(), mod_depth_.get() });
329
331}
332
333void FlangerSection::setActive(bool active) {
334 flanger_response_->setActive(active);
336}
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
cr::Value resonance
Resonance factor for this formant.
Definition formant_filter.cpp:18
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 classes for OpenGL-based buttons used in the Vital synth UI.
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.