Vital
Loading...
Searching...
No Matches
peak_meter_viewer.cpp
Go to the documentation of this file.
1#include "peak_meter_viewer.h"
2
3#include "skin.h"
4#include "shaders.h"
6#include "utils.h"
7
8namespace {
9 constexpr float kClampDecay = 0.014f;
10 constexpr float kMinDb = -80.0f;
11 constexpr float kMaxDb = 6.0f;
12} // namespace;
13
14PeakMeterViewer::PeakMeterViewer(bool left) : shader_(nullptr), clamped_(0.0f), left_(left) {
16 peak_output_ = nullptr;
17 peak_memory_output_ = nullptr;
18 float position_vertices[kNumPositions] = {
19 -1.0f, 1.0f,
20 -1.0f, -1.0f,
21 1.0f, -1.0f,
22 1.0f, 1.0f,
23 };
24 memcpy(position_vertices_, position_vertices, kNumPositions * sizeof(float));
25
26 int position_triangles[6] = {
27 0, 1, 2,
28 2, 3, 0
29 };
30 memcpy(position_triangles_, position_triangles, kNumTriangleIndices * sizeof(int));
31
32 vertex_buffer_ = 0;
33 triangle_buffer_ = 0;
34}
35
37
39 if (peak_output_ == nullptr || peak_memory_output_ == nullptr) {
40 SynthGuiInterface* parent = findParentComponentOfClass<SynthGuiInterface>();
41 peak_output_ = parent->getSynth()->getStatusOutput("peak_meter");
42 peak_memory_output_ = parent->getSynth()->getStatusOutput("peak_meter_memory");
43 }
44
46}
47
49 OpenGlComponent::init(open_gl);
50
51 open_gl.context.extensions.glGenBuffers(1, &vertex_buffer_);
52 open_gl.context.extensions.glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_);
53
54 GLsizeiptr vert_size = static_cast<GLsizeiptr>(static_cast<size_t>(kNumPositions * sizeof(float)));
55 open_gl.context.extensions.glBufferData(GL_ARRAY_BUFFER, vert_size,
56 position_vertices_, GL_STATIC_DRAW);
57
58 open_gl.context.extensions.glGenBuffers(1, &triangle_buffer_);
59 open_gl.context.extensions.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, triangle_buffer_);
60
61 GLsizeiptr tri_size = static_cast<GLsizeiptr>(static_cast<size_t>(kNumTriangleIndices * sizeof(float)));
62 open_gl.context.extensions.glBufferData(GL_ELEMENT_ARRAY_BUFFER, tri_size,
63 position_triangles_, GL_STATIC_DRAW);
64
66 shader_->use();
67 position_ = getAttribute(open_gl, *shader_, "position");
68 color_from_ = getUniform(open_gl, *shader_, "color_from");
69 color_to_ = getUniform(open_gl, *shader_, "color_to");
70}
71
72void PeakMeterViewer::updateVertices() {
73 if (peak_output_ == nullptr)
74 return;
75
76 float val = peak_output_->value()[left_ ? 0 : 1];
77 if (val > 1.0f)
78 clamped_ = 1.0f;
79
80 float db = vital::utils::magnitudeToDb(val);
81 float t = std::max((db - kMinDb) / (kMaxDb - kMinDb), 0.0f);
82 t *= t;
83 float position = vital::utils::interpolate(-1.0f, 1.0f, t);
84 position_vertices_[0] = -1.0f;
85 position_vertices_[2] = -1.0f;
86 position_vertices_[4] = position;
87 position_vertices_[6] = position;
88}
89
90void PeakMeterViewer::updateVerticesMemory() {
91 if (peak_memory_output_ == nullptr)
92 return;
93
94 float val = peak_memory_output_->value()[left_ ? 0 : 1];
95 if (val > 1.0f)
96 clamped_ = 1.0f;
97
98 float db = vital::utils::magnitudeToDb(val);
99 float t = std::max((db - kMinDb) / (kMaxDb - kMinDb), 0.0f);
100 t *= t;
101 float position = vital::utils::interpolate(-1.0f, 1.0f, t);
102 float width = 2.0f / getWidth();
103 position_vertices_[0] = position - width;
104 position_vertices_[2] = position - width;
105 position_vertices_[4] = position;
106 position_vertices_[6] = position;
107}
108
109void PeakMeterViewer::render(OpenGlWrapper& open_gl, bool animate) {
110 if (!animate || peak_output_ == nullptr)
111 return;
112
113 glEnable(GL_BLEND);
114 glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
115
116 setViewPort(open_gl);
117 shader_->use();
118
119 Colour color_from, color_to;
120 if (clamped_ > 0.0f) {
121 color_from = findColour(Skin::kWidgetAccent1, true);
122 color_to = findColour(Skin::kWidgetAccent2, true);
123 }
124 else {
125 color_from = findColour(Skin::kWidgetSecondary1, true);
126 color_to = findColour(Skin::kWidgetSecondary2, true);
127 }
128
129 color_from_->set(color_from.getFloatRed(), color_from.getFloatGreen(),
130 color_from.getFloatBlue(), color_from.getFloatAlpha());
131 color_to_->set(color_to.getFloatRed(), color_to.getFloatGreen(),
132 color_to.getFloatBlue(), color_to.getFloatAlpha());
133
134 updateVertices();
135 draw(open_gl);
136 updateVerticesMemory();
137 draw(open_gl);
138
139 clamped_ = vital::utils::max(clamped_ - kClampDecay, 0.0f);
140
141 float rounding = std::min(getHeight() / 3.0f, findValue(Skin::kWidgetRoundedCorner) * 0.5f);
142 renderCorners(open_gl, animate, findColour(Skin::kBackground, true), rounding);
143}
144
146 open_gl.context.extensions.glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_);
147 GLsizeiptr vert_size = static_cast<GLsizeiptr>(static_cast<size_t>(kNumPositions * sizeof(float)));
148 open_gl.context.extensions.glBufferData(GL_ARRAY_BUFFER, vert_size,
149 position_vertices_, GL_STATIC_DRAW);
150
151 open_gl.context.extensions.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, triangle_buffer_);
152
153 open_gl.context.extensions.glVertexAttribPointer(position_->attributeID, 2, GL_FLOAT,
154 GL_FALSE, 2 * sizeof(float), nullptr);
155 open_gl.context.extensions.glEnableVertexAttribArray(position_->attributeID);
156
157 glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr);
158
159 open_gl.context.extensions.glBindBuffer(GL_ARRAY_BUFFER, 0);
160 open_gl.context.extensions.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
161}
162
165
166 shader_ = nullptr;
167 position_ = nullptr;
168 color_from_ = nullptr;
169 color_to_ = nullptr;
170 open_gl.context.extensions.glDeleteBuffers(1, &vertex_buffer_);
171 open_gl.context.extensions.glDeleteBuffers(1, &triangle_buffer_);
172}
173
175 float t = -kMinDb / (kMaxDb - kMinDb);
176 t *= t;
177 float x = getWidth() * t;
178 Colour background = findColour(Skin::kWidgetBackground, true);
179 g.setColour(background.interpolatedWith(findColour(Skin::kBackground, true), 0.5f));
180 g.fillRect(x, 0.0f, getWidth() - x, 1.0f * getHeight());
181
182 g.setColour(background);
183 g.fillRect(0.0f, 0.0f, x, 1.0f * getHeight());
184
185 g.setColour(findColour(Skin::kLightenScreen, true));
186 g.fillRect((int)x, 0, 1, getHeight());
187}
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
void addRoundedCorners()
Adds rounded corners to the component's edges.
Definition open_gl_component.cpp:138
virtual void resized() override
Called when the component is resized.
Definition open_gl_component.cpp:121
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
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
virtual void destroy(OpenGlWrapper &open_gl)
Destroys any OpenGL-specific resources allocated by this component.
Definition open_gl_component.cpp:168
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
virtual void init(OpenGlWrapper &open_gl)
Initializes any OpenGL-specific resources needed by the component.
Definition open_gl_component.cpp:148
void init(OpenGlWrapper &open_gl) override
Initializes the OpenGL buffers and shader for drawing the meter.
Definition peak_meter_viewer.cpp:48
void paintBackground(Graphics &g) override
Paints a background for the meter, showing ranges or thresholds.
Definition peak_meter_viewer.cpp:174
void render(OpenGlWrapper &open_gl, bool animate) override
Renders the peak meter using OpenGL.
Definition peak_meter_viewer.cpp:109
void resized() override
Called when the component is resized. Initializes status outputs if needed.
Definition peak_meter_viewer.cpp:38
void draw(OpenGlWrapper &open_gl)
Draws the peak meter quads according to current peak and memory values.
Definition peak_meter_viewer.cpp:145
void destroy(OpenGlWrapper &open_gl) override
Releases any OpenGL resources associated with this component.
Definition peak_meter_viewer.cpp:163
PeakMeterViewer(bool left)
Constructs a PeakMeterViewer.
Definition peak_meter_viewer.cpp:14
virtual ~PeakMeterViewer()
Destructor.
Definition peak_meter_viewer.cpp:36
@ kGainMeterVertex
Definition shaders.h:33
@ kGainMeterFragment
Definition shaders.h:61
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
@ kWidgetRoundedCorner
Definition skin.h:104
@ kWidgetAccent1
Definition skin.h:171
@ kBackground
Definition skin.h:128
@ kWidgetBackground
Definition skin.h:173
@ kWidgetSecondary1
Definition skin.h:168
@ kLightenScreen
Definition skin.h:141
@ kWidgetSecondary2
Definition skin.h:169
@ kWidgetAccent2
Definition skin.h:172
const vital::StatusOutput * getStatusOutput(const std::string &name)
Retrieves a status output by name.
Definition synth_base.cpp:262
An interface class linking the Vital synthesizer backend (SynthBase) with a GUI.
Definition synth_gui_interface.h:56
SynthBase * getSynth()
Returns the SynthBase instance this interface is managing.
Definition synth_gui_interface.h:85
force_inline poly_float value() const
Returns the current status value.
Definition synth_module.h:49
force_inline poly_float magnitudeToDb(poly_float value)
Converts a magnitude value to decibels (vectorized).
Definition poly_utils.h:144
force_inline poly_float max(poly_float left, poly_float right)
Returns the maximum of two poly_floats lane-by-lane.
Definition poly_utils.h:327
force_inline poly_float interpolate(poly_float from, poly_float to, mono_float t)
Performs a linear interpolation between two poly_floats using a scalar t in [0..1].
Definition poly_utils.h:182
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
Provides various utility functions, classes, and constants for audio, math, and general-purpose opera...