Vital
Loading...
Searching...
No Matches
sample_viewer.cpp
Go to the documentation of this file.
1
3
4#include "sample_viewer.h"
5
6#include "skin.h"
8
10SampleViewer::SampleViewer() : OpenGlLineRenderer(kResolution), bottom_(kResolution),
11 dragging_overlay_(Shaders::kColorFragment) {
12 addAndMakeVisible(bottom_);
13 animate_ = false;
14 active_ = true;
15 sample_phase_output_ = nullptr;
16 last_phase_ = 0.0f;
17 sample_ = nullptr;
18 dragging_audio_file_ = false;
20
21 dragging_overlay_.setTargetComponent(this);
22
23 setFill(true);
24 bottom_.setFill(true);
25 setLineWidth(2.0f);
26 bottom_.setLineWidth(2.0f);
27}
28
31
35void SampleViewer::audioFileLoaded(const File& file) {
36 for (Listener* listener : listeners_)
37 listener->sampleLoaded(file);
38
40}
41
44 dragging_audio_file_ = false;
46}
47
50 if (sample_ == nullptr)
51 return;
52
53 double sample_length = sample_->originalLength();
54 const vital::mono_float* buffer = sample_->buffer();
55 float center = getHeight() / 2.0f;
56 for (int i = 0; i < kResolution; ++i) {
57 int start_index = std::min<int>(sample_length * i / kResolution, sample_length);
58 int end_index = std::min<int>((sample_length * (i + 1) + kResolution - 1) / kResolution, sample_length);
59 float max = buffer[start_index];
60 for (int i = start_index + 1; i < end_index; ++i)
61 max = std::max(max, buffer[i]);
62 setYAt(i, center - max * center);
63 bottom_.setYAt(i, center + max * center);
64 }
65}
66
69std::string SampleViewer::getName() {
70 if (sample_)
71 return sample_->getName();
72 return "";
73}
74
78 bottom_.setBounds(getLocalBounds());
79 dragging_overlay_.setColor(findColour(Skin::kOverlayScreen, true));
80
81 for (int i = 0; i < kResolution; ++i) {
82 float t = i / (kResolution - 1.0f);
83 setXAt(i, getWidth() * t);
84 bottom_.setXAt(i, getWidth() * t);
85 }
86
87 if (sample_phase_output_ == nullptr) {
88 SynthGuiInterface* parent = findParentComponentOfClass<SynthGuiInterface>();
89 if (parent)
90 sample_phase_output_ = parent->getSynth()->getStatusOutput("sample_phase");
91 }
92
95}
96
101void SampleViewer::render(OpenGlWrapper& open_gl, bool animate) {
102 animate_ = animate;
103
104 float boost_amount = findValue(Skin::kWidgetLineBoost);
105 float fill_boost_amount = findValue(Skin::kWidgetFillBoost);
106 setBoostAmount(boost_amount);
107 bottom_.setBoostAmount(boost_amount);
108 setFillBoostAmount(fill_boost_amount);
109 bottom_.setFillBoostAmount(fill_boost_amount);
110
111 if (sample_ == nullptr)
112 return;
113
114 int sample_length = sample_->originalLength();
115 if (sample_phase_output_ == nullptr || sample_length == 0)
116 return;
117
118 // Determine if voice changed
119 vital::poly_float encoded_phase = sample_phase_output_->value();
120 std::pair<vital::poly_float, vital::poly_float> decoded = vital::utils::decodePhaseAndVoice(encoded_phase);
121 vital::poly_float phase = decoded.first;
122 vital::poly_float voice = decoded.second;
123
124 vital::poly_mask switch_mask = vital::poly_float::notEqual(voice, last_voice_);
125 vital::poly_float phase_reset = vital::utils::max(0.0f, phase);
126 last_phase_ = vital::utils::maskLoad(last_phase_, phase_reset, switch_mask);
127
128 if (!sample_phase_output_->isClearValue(phase) && vital::poly_float::notEqual(phase, 0.0f).anyMask() != 0) {
129 vital::poly_float phase_delta = vital::poly_float::abs(phase - last_phase_);
130 vital::poly_float decay = vital::poly_float(1.0f) - phase_delta * kSpeedDecayMult;
131 decay = vital::utils::clamp(decay, kBoostDecay, 1.0f);
132 decayBoosts(decay);
133 bottom_.decayBoosts(decay);
134
135 if (animate_) {
136 boostRange(last_phase_, phase, 0, decay);
137 bottom_.boostRange(last_phase_, phase, 0, decay);
138 }
139 }
140 else {
142 bottom_.decayBoosts(kBoostDecay);
143 }
144
145 last_phase_ = phase;
146 last_voice_ = voice;
147
148 float fill_fade = 0.0f;
149 if (parent_)
151
152 // First pass for underlying lines
153 Colour line, fill;
154 if (isActive()) {
155 line = findColour(Skin::kWidgetPrimary2, true);
156 fill = findColour(Skin::kWidgetSecondary2, true);
157 }
158 else {
159 line = findColour(Skin::kWidgetPrimaryDisabled, true);
160 fill = findColour(Skin::kWidgetSecondaryDisabled, true);
161 }
162
163 setColor(line);
164 bottom_.setColor(line);
165 setFillColors(fill.withMultipliedAlpha(1.0f - fill_fade), fill);
166 bottom_.setFillColors(fill.withMultipliedAlpha(1.0f - fill_fade), fill);
167
168 drawLines(open_gl, false);
169 bottom_.drawLines(open_gl, false);
170
171 // Second pass for boosted lines
172 if (isActive()) {
173 line = findColour(Skin::kWidgetPrimary1, true);
174 fill = findColour(Skin::kWidgetSecondary1, true);
175 }
176 else {
177 line = findColour(Skin::kWidgetPrimaryDisabled, true);
178 fill = findColour(Skin::kWidgetSecondaryDisabled, true);
179 }
180
181 setColor(line);
182 bottom_.setColor(line);
183 setFillColors(fill.withMultipliedAlpha(1.0f - fill_fade), fill);
184 bottom_.setFillColors(fill.withMultipliedAlpha(1.0f - fill_fade), fill);
185
186 drawLines(open_gl, anyBoostValue());
187 bottom_.drawLines(open_gl, anyBoostValue());
188
189 // Render overlay if dragging a file
190 if (dragging_audio_file_)
191 dragging_overlay_.render(open_gl, animate);
192 renderCorners(open_gl, animate);
193}
virtual void resized() override
Called when the component is resized.
Definition open_gl_component.cpp:121
void addBottomRoundedCorners()
Adds rounded corners only at the bottom of the component.
Definition open_gl_component.cpp:143
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
const SynthSection * parent_
Pointer to parent SynthSection for skin lookups.
Definition open_gl_component.h:256
A component for rendering lines with optional filling and boost effects using OpenGL.
Definition open_gl_line_renderer.h:16
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
void decayBoosts(vital::poly_float mult)
Decays all boosts by a multiplicative factor, allowing animated damping.
Definition open_gl_line_renderer.cpp:185
force_inline void setFillBoostAmount(float boost_amount)
Sets the boost amount that affects fill thickness.
Definition open_gl_line_renderer.h:147
force_inline void setBoostAmount(float boost_amount)
Sets the boost amount that affects line thickness.
Definition open_gl_line_renderer.h:144
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
bool anyBoostValue()
Checks if any boost value is set.
Definition open_gl_line_renderer.h:202
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 boostRange(float *boosts, float start, float end, int buffer_vertices, float min)
Boosts a range for the given boost array.
Definition open_gl_line_renderer.cpp:128
void drawLines(OpenGlWrapper &open_gl, bool left)
Draws the line and optional fill using OpenGL.
Definition open_gl_line_renderer.cpp:386
void setTargetComponent(Component *target_component)
Sets a target component to help position the quads.
Definition open_gl_multi_quad.h:358
virtual void render(OpenGlWrapper &open_gl, bool animate) override
Renders the quads using OpenGL.
Definition open_gl_multi_quad.cpp:92
force_inline void setColor(Colour color)
Sets the base color for the quads.
Definition open_gl_multi_quad.h:102
Interface for objects that want to be notified when a sample is loaded.
Definition sample_viewer.h:32
virtual ~SampleViewer()
Destructor.
Definition sample_viewer.cpp:30
bool isActive() const
Definition sample_viewer.h:77
std::string getName()
Definition sample_viewer.cpp:69
SampleViewer()
Constructor.
Definition sample_viewer.cpp:10
static constexpr float kResolution
The resolution of the waveform, in number of points.
Definition sample_viewer.h:24
static constexpr float kBoostDecay
The decay factor for line boosts.
Definition sample_viewer.h:26
void repaintAudio()
Repaints the waveform after an audio update.
Definition sample_viewer.cpp:43
void render(OpenGlWrapper &open_gl, bool animate) override
Definition sample_viewer.cpp:101
static constexpr float kSpeedDecayMult
The multiplier for decay when lines move quickly.
Definition sample_viewer.h:28
void audioFileLoaded(const File &file) override
Definition sample_viewer.cpp:35
void setLinePositions()
Sets the line positions (y-values) of the waveform based on the current sample.
Definition sample_viewer.cpp:49
void resized() override
Handles component resizing. Adjusts waveform geometry.
Definition sample_viewer.cpp:77
Manages and provides access to vertex and fragment shaders used by the OpenGL rendering pipeline.
Definition shaders.h:19
@ kWidgetFillFade
Definition skin.h:108
@ kWidgetLineBoost
Definition skin.h:106
@ kWidgetFillBoost
Definition skin.h:109
@ 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
@ kOverlayScreen
Definition skin.h:140
@ kWidgetSecondary2
Definition skin.h:169
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
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
std::string getName() const
Returns the user-facing name of the sample.
Definition sample_source.h:91
force_inline const mono_float * buffer() const
Returns a pointer to the (current) left channel buffer at the base upsample level.
Definition sample_source.h:121
force_inline int originalLength() const
Returns the length of the originally loaded sample in frames.
Definition sample_source.h:99
force_inline bool isClearValue(poly_float value) const
Checks if a given poly_float is the special "clear" value.
Definition synth_module.h:81
force_inline poly_float value() const
Returns the current status value.
Definition synth_module.h:49
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 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 maskLoad(poly_float zero_value, poly_float one_value, poly_mask reset_mask)
Selects between two values (zero_value or one_value) based on a mask in each lane.
Definition poly_utils.h:351
force_inline std::pair< poly_float, poly_float > decodePhaseAndVoice(poly_float encoded)
Decodes a phase and voice from an encoded float, returning (phase, voice).
Definition poly_utils.h:987
float mono_float
Definition common.h:33
Declares the SampleViewer class that displays and animates a waveform sample.
A helper struct containing references to OpenGL context, shaders, and display scale.
Definition shaders.h:174
Represents a vector of floating-point values using SIMD instructions.
Definition poly_values.h:600
static force_inline simd_type vector_call abs(simd_type value)
Computes the absolute value of each element in the SIMD float register.
Definition poly_values.h:935
static force_inline mask_simd_type vector_call notEqual(simd_type one, simd_type two)
Compares two SIMD float registers for non-equality, element-wise.
Definition poly_values.h:1003
Represents a vector of integer values using SIMD instructions.
Definition poly_values.h:56