Vital
Loading...
Searching...
No Matches
file_source_overlay.cpp
Go to the documentation of this file.
2
4#include "fonts.h"
5#include "skin.h"
7#include "tuning.h"
8#include "wave_frame.h"
9#include "sample_viewer.h"
10
11namespace {
12 const std::string kFadeLookup[] = {
13 "File Blend",
14 "None",
15 "Time",
16 "Spectral",
17 };
18 const std::string kPhaseLookup[] = {
19 "None",
20 "Clear",
21 "Vocode",
22 };
23
35 float windowTextToSize(String text, int sample_rate) {
36 static constexpr float kMaxWindowSize = 9999.9f;
37 String trimmed = text.trim();
38 int note_midi = Tuning::noteToMidiKey(text);
39 if (note_midi < 0 || note_midi >= vital::kMidiSize)
40 return vital::utils::clamp(trimmed.getFloatValue(), 1.0f, kMaxWindowSize);
41 return sample_rate / vital::utils::midiNoteToFrequency(note_midi);
42 }
43
49 float positionTextToSize(String text) {
50 return text.trim().getFloatValue();
51 }
52}
53
54AudioFileViewer::AudioFileViewer() : SynthSection("Audio File"), top_(kResolution), bottom_(kResolution),
55 dragging_quad_(Shaders::kRoundedRectangleFragment), sample_rate_(0),
56 file_source_(nullptr) {
57 window_position_ = 0.0f;
58 window_size_ = 1.0f;
59 window_fade_ = 0.0f;
60
61 addOpenGlComponent(&top_);
62 addOpenGlComponent(&bottom_);
63 addOpenGlComponent(&dragging_quad_);
64 top_.setInterceptsMouseClicks(false, false);
65 bottom_.setInterceptsMouseClicks(false, false);
66
67 top_.setFill(true);
68 bottom_.setFill(true);
69
70 dragging_quad_.setTargetComponent(this);
71}
72
74 static constexpr float kBuffer = 0.1f;
75 static constexpr float kCenterAlpha = 0.1f;
76
77 int buffer = getHeight() * kBuffer;
78 Rectangle<int> bounds(0, buffer, getWidth(), getHeight() - 2 * buffer);
79 top_.setBounds(bounds);
80 bottom_.setBounds(bounds);
81
82 top_.setLineWidth(3.0f);
83 bottom_.setLineWidth(3.0f);
84 Colour line = findColour(Skin::kWidgetPrimary1, true);
85 Colour fill = findColour(Skin::kWidgetSecondary1, true).withAlpha(kCenterAlpha);
86 top_.setColor(line);
87 bottom_.setColor(line);
88 top_.setFillColor(fill);
89 bottom_.setFillColor(fill);
90 dragging_quad_.setColor(findColour(Skin::kOverlayScreen, true));
91
92 float line_boost = findValue(Skin::kWidgetLineBoost);
93 top_.setBoostAmount(line_boost);
94 bottom_.setBoostAmount(line_boost);
95
96 top_.setFillBoostAmount(1.0f / kCenterAlpha);
97 bottom_.setFillBoostAmount(1.0f / kCenterAlpha);
98
99 float delta = getWidth() / (kResolution - 1.0f);
100 for (int i = 0; i < kResolution; ++i) {
101 top_.setXAt(i, delta * i);
102 bottom_.setXAt(i, delta * i);
103 }
104
106}
107
109 float center = top_.getHeight() * 0.5f;
110 for (int i = 0; i < kResolution; ++i) {
111 top_.setYAt(i, center);
112 bottom_.setYAt(i, center);
113 }
114}
115
117 if (file_source_ == nullptr) {
119 return;
120 }
121
122 const FileSource::SampleBuffer* sample_buffer = file_source_->buffer();
123 if (sample_buffer->size == 0 || sample_buffer->data == nullptr) {
125 return;
126 }
127
128 const float* buffer = sample_buffer->data.get();
129 int sample_length = sample_buffer->size;
130
131 float center = top_.getHeight() * 0.5f;
132 for (int i = 0; i < kResolution; ++i) {
133 int start_index = std::min<int>(sample_length * i / kResolution, sample_length);
134 int end_index = std::min<int>((sample_length * (i + 1) + kResolution - 1) / kResolution, sample_length);
135 float max = buffer[start_index];
136 for (int i = start_index + 1; i < end_index; ++i)
137 max = std::max(max, buffer[i]);
138 top_.setYAt(i, center - max * center);
139 bottom_.setYAt(i, center + max * center);
140 }
141
143}
144
146 if (file_source_ == nullptr)
147 return;
148
149 const FileSource::SampleBuffer* sample_buffer = file_source_->buffer();
150 if (sample_buffer->size == 0 || sample_buffer->data == nullptr)
151 return;
152
153 window_size_ = file_source_->getWindowSize() / sample_buffer->size;
154
155 float fade_length = std::max(window_fade_ * window_size_, 1.0f / kResolution);
156 float start = window_position_ - fade_length * 0.5f;
157 float end = window_position_ + window_size_ + fade_length * 0.5f;
158
159 for (int i = 0; i < kResolution; ++i) {
160 float position = i / (kResolution - 1.0f);
161 float window_phase = std::min(position - start, end - position) / fade_length;
162 window_phase = std::max(std::min(window_phase, 1.0f), 0.0f) * vital::kPi;
163 float window_value = 0.5f - cosf(window_phase) * 0.5f;
164
165 top_.setBoostLeft(i, window_value);
166 bottom_.setBoostLeft(i, window_value);
167 }
168}
169
170void AudioFileViewer::audioFileLoaded(const File& file) {
171 static constexpr int kMaxFileSamples = 176400;
172 std::unique_ptr<AudioFormatReader> format_reader(format_manager_.createReaderFor(file));
173
174 if (format_reader) {
175 int num_samples = (int)std::min<long long>(format_reader->lengthInSamples, kMaxFileSamples);
176 sample_buffer_.setSize(format_reader->numChannels, num_samples);
177 format_reader->read(&sample_buffer_, 0, num_samples, 0, true, true);
178 }
179
180 dragging_quad_.setActive(false);
181}
182
183void AudioFileViewer::fileDragEnter(const StringArray& files, int x, int y) {
184 dragging_quad_.setActive(true);
185}
186
187void AudioFileViewer::fileDragExit(const StringArray& files) {
188 dragging_quad_.setActive(false);
189}
190
191float AudioFileViewer::updateMousePosition(Point<float> position) {
192 float ratio = (position.x - last_mouse_position_.x) / getWidth();
193 last_mouse_position_ = position;
194 return ratio;
195}
196
197void AudioFileViewer::mouseDown(const MouseEvent& e) {
198 updateMousePosition(e.position);
199}
200
201void AudioFileViewer::mouseDrag(const MouseEvent& e) {
202 float ratio = updateMousePosition(e.position);
203
204 for (DragListener* listener : drag_listeners_)
205 listener->positionMovedRelative(ratio, false);
206}
207
208void AudioFileViewer::mouseUp(const MouseEvent& e) {
209 float ratio = updateMousePosition(e.position);
210
211 for (DragListener* listener : drag_listeners_)
212 listener->positionMovedRelative(ratio, true);
213}
214
215FileSourceOverlay::FileSourceOverlay() : WavetableComponentOverlay("FILE SOURCE"), file_source_(nullptr) {
216 current_frame_ = nullptr;
217 load_button_ = std::make_unique<TextButton>("LOAD");
218 addAndMakeVisible(load_button_.get());
219 load_button_->addListener(this);
220 load_button_->setLookAndFeel(TextLookAndFeel::instance());
221 load_button_->setButtonText("LOAD");
222
223 fade_style_ = std::make_unique<TextSelector>("Fade Style");
224 addSlider(fade_style_.get());
225 fade_style_->setAlwaysOnTop(true);
226 fade_style_->getImageComponent()->setAlwaysOnTop(true);
227 fade_style_->addListener(this);
228 fade_style_->setRange(0, FileSource::kNumFadeStyles - 1, 1);
229 fade_style_->setSliderStyle(Slider::RotaryHorizontalVerticalDrag);
230 fade_style_->setLookAndFeel(TextLookAndFeel::instance());
231 fade_style_->setStringLookup(kFadeLookup);
232 fade_style_->setLongStringLookup(kFadeLookup);
233
234 phase_style_ = std::make_unique<TextSelector>("Phase Style");
235 addSlider(phase_style_.get());
236 phase_style_->setAlwaysOnTop(true);
237 phase_style_->getImageComponent()->setAlwaysOnTop(true);
238 phase_style_->addListener(this);
239 phase_style_->setRange(0, FileSource::kNumPhaseStyles - 1, 1);
240 phase_style_->setSliderStyle(Slider::RotaryHorizontalVerticalDrag);
241 phase_style_->setStringLookup(kPhaseLookup);
242 phase_style_->setLookAndFeel(TextLookAndFeel::instance());
243 phase_style_->setLongStringLookup(kPhaseLookup);
244
245 normalize_gain_ = std::make_unique<OpenGlToggleButton>("NORMALIZE");
246 addAndMakeVisible(normalize_gain_.get());
247 addOpenGlComponent(normalize_gain_->getGlComponent());
248 normalize_gain_->setAlwaysOnTop(true);
249 normalize_gain_->getGlComponent()->setAlwaysOnTop(true);
250 normalize_gain_->setNoBackground();
252 normalize_gain_->addListener(this);
253
254 audio_thumbnail_ = std::make_unique<AudioFileViewer>();
256 audio_thumbnail_->setAlwaysOnTop(true);
257 audio_thumbnail_->addListener(this);
258 audio_thumbnail_->addDragListener(this);
259
260#if !defined(NO_TEXT_ENTRY)
261 start_position_ = std::make_unique<OpenGlTextEditor>("Start Position");
262 addAndMakeVisible(start_position_.get());
263 addOpenGlComponent(start_position_->getImageComponent());
264 start_position_->setAlwaysOnTop(true);
265 start_position_->getImageComponent()->setAlwaysOnTop(true);
266 start_position_->addListener(this);
268 start_position_->setJustification(Justification::centred);
269
270 window_size_ = std::make_unique<OpenGlTextEditor>("Window Size");
271 addAndMakeVisible(window_size_.get());
272 addOpenGlComponent(window_size_->getImageComponent());
273 window_size_->setAlwaysOnTop(true);
274 window_size_->getImageComponent()->setAlwaysOnTop(true);
275 window_size_->addListener(this);
276 window_size_->setLookAndFeel(TextLookAndFeel::instance());
277 window_size_->setJustification(Justification::centred);
278#endif
279
280 window_fade_ = std::make_unique<SynthSlider>("File Source Window Fade");
281 addSlider(window_fade_.get());
282 window_fade_->setAlwaysOnTop(true);
283 window_fade_->getImageComponent()->setAlwaysOnTop(true);
284 window_fade_->addListener(this);
285 window_fade_->setRange(0.0f, 1.0f);
286 window_fade_->setDoubleClickReturnValue(true, 1.0f);
287 window_fade_->setLookAndFeel(TextLookAndFeel::instance());
288 window_fade_->setSliderStyle(Slider::RotaryHorizontalVerticalDrag);
289
292 controls_background_.addTitle("POSITION");
293 controls_background_.addTitle("WINDOW SIZE");
294 controls_background_.addTitle("WINDOW FADE");
295 controls_background_.addTitle("BLEND STYLE");
296 controls_background_.addTitle("PHASE STYLE");
298}
299
301
303 if (keyframe == nullptr)
304 current_frame_ = nullptr;
305 else if (keyframe->owner() == file_source_) {
307
308 double start_position = current_frame_->getStartPosition();
309 double window_fade = current_frame_->getWindowFade();
310 double window_size = file_source_->getWindowSize();
311
312 if (start_position_)
313 start_position_->setText(String(start_position, 1));
314 window_fade_->setValue(window_fade, dontSendNotification);
315
316 if (window_size_)
317 window_size_->setText(String(window_size, 1));
318
319 double num_samples = file_source_->buffer()->size;
320 if (num_samples) {
321 audio_thumbnail_->setWindowPosition(start_position / num_samples);
322 audio_thumbnail_->setWindowSize(window_size / num_samples);
323 }
324 else {
325 audio_thumbnail_->setWindowPosition(0.0f);
326 audio_thumbnail_->setWindowSize(1.0f);
327 }
328 audio_thumbnail_->setWindowFade(window_fade);
329
330 normalize_gain_->setToggleState(file_source_->getNormalizeGain(), dontSendNotification);
331 fade_style_->setValue(file_source_->getFadeStyle(), dontSendNotification);
332 phase_style_->setValue(file_source_->getPhaseStyle(), dontSendNotification);
333 fade_style_->redoImage();
334 phase_style_->redoImage();
335 }
336}
337
338void FileSourceOverlay::setEditBounds(Rectangle<int> bounds) {
339 static constexpr float kTextBoxWidthHeightRatio = 2.5f;
340 static constexpr float kWindowFadeWidthHeightRatio = 3.0f;
341 static constexpr float kSelectorWidthHeightRatio = 3.0f;
342 static constexpr float kNormalizeWidthHeightRatio = 2.5f;
343 static constexpr float kBorderWidthHeightRatio = 1.5f;
344
345 if (bounds.getWidth() <= 0)
346 return;
347
348 int padding = getPadding();
349 int text_box_width = bounds.getHeight() * kTextBoxWidthHeightRatio;
350 int window_fade_width = bounds.getHeight() * kWindowFadeWidthHeightRatio;
351 int selector_width = bounds.getHeight() * kSelectorWidthHeightRatio;
352 int normalize_width = bounds.getHeight() * kNormalizeWidthHeightRatio;
353 int border_width = bounds.getHeight() * kBorderWidthHeightRatio;
354 int total_width = bounds.getWidth() - 2 * border_width;
355 int audio_width = total_width - normalize_width - 2 * selector_width - window_fade_width -
356 2 * text_box_width - 6 * padding;
357
358 setControlsWidth(total_width);
360
361 int title_height = WavetableComponentOverlay::kTitleHeightRatio * bounds.getHeight();
362 int x = border_width;
363 int y = bounds.getY();
364 int y_title = y + title_height;
365 int height = bounds.getHeight();
366 int height_title = height - title_height;
367 phase_style_->setTextHeightPercentage(0.4f);
368 fade_style_->setTextHeightPercentage(0.4f);
369 audio_thumbnail_->setBounds(x + 1, y + 1, audio_width - 1, height - 2);
370
371 int edit_x = audio_thumbnail_->getRight() + padding;
372 if (start_position_) {
373 start_position_->setBounds(edit_x, y_title, text_box_width, height_title - 1);
374 window_size_->setBounds(start_position_->getRight() + padding, y_title, text_box_width, height_title - 1);
375 edit_x = window_size_->getRight() + padding;
376 }
377 window_fade_->setBounds(edit_x, y_title, window_fade_width, height_title);
378 fade_style_->setBounds(window_fade_->getRight() + padding, y_title, selector_width, height_title);
379 phase_style_->setBounds(fade_style_->getRight() + padding, y_title, selector_width, height_title);
380 int normalize_padding = height / 6;
381 normalize_gain_->setBounds(phase_style_->getRight() + padding, y + normalize_padding,
382 normalize_width, height - 2 * normalize_padding);
383
385 controls_background_.addLine(audio_width);
386 controls_background_.addLine(audio_width + text_box_width + padding);
387 controls_background_.addLine(audio_width + 2 * text_box_width + 2 * padding);
388 controls_background_.addLine(audio_width + 2 * text_box_width + window_fade_width + 3 * padding);
389 controls_background_.addLine(audio_width + 2 * text_box_width + window_fade_width + selector_width + 4 * padding);
390 controls_background_.addLine(audio_width + 2 * text_box_width + window_fade_width + 2 * selector_width + 5 * padding);
391
393 setTextEditorVisuals(window_size_.get(), height_title);
394 setTextEditorVisuals(start_position_.get(), height_title);
395
396 start_position_->redoImage();
397 window_size_->redoImage();
398 }
399 window_fade_->redoImage();
400 fade_style_->redoImage();
401 phase_style_->redoImage();
402}
403
404void FileSourceOverlay::sliderValueChanged(Slider* moved_slider) {
405 if (current_frame_ == nullptr || file_source_ == nullptr)
406 return;
407
408 if (moved_slider == window_fade_.get()) {
410 audio_thumbnail_->setWindowFade(window_fade_->getValue());
411 }
412
413 if (moved_slider == fade_style_.get())
414 file_source_->setFadeStyle((FileSource::FadeStyle)static_cast<int>(fade_style_->getValue()));
415
416 if (moved_slider == phase_style_.get())
417 file_source_->setPhaseStyle((FileSource::PhaseStyle)static_cast<int>(phase_style_->getValue()));
418
419 notifyChanged(moved_slider == fade_style_.get() || moved_slider == phase_style_.get());
420}
421
422void FileSourceOverlay::sliderDragEnded(Slider* moved_slider) {
423 notifyChanged(true);
424}
425
426void FileSourceOverlay::loadFile(const File& file) {
427 if (!file.exists() || file_source_ == nullptr)
428 return;
429
430 audio_thumbnail_->audioFileLoaded(file);
431 AudioSampleBuffer* sample_buffer = audio_thumbnail_->getSampleBuffer();
432 int sample_rate = audio_thumbnail_->getSampleRate();
433 file_source_->loadBuffer(sample_buffer->getReadPointer(0, 0), sample_buffer->getNumSamples(), sample_rate);
435 audio_thumbnail_->setAudioPositions();
436
438 if (start_position_)
440
441 notifyChanged(true);
442}
443
445 FileChooser load_file("Load Audio File", File::getSpecialLocation(File::userHomeDirectory), String("*.wav"));
446 if (load_file.browseForFileToOpen())
447 loadFile(load_file.getResult());
448}
449
450void FileSourceOverlay::buttonClicked(Button* clicked_button) {
451 if (file_source_ == nullptr)
452 return;
453
454 if (clicked_button == load_button_.get())
456 else if (clicked_button == normalize_gain_.get()) {
458 notifyChanged(true);
459 }
460}
461
463 loadFile(file);
464}
465
467 if (&text_editor == window_size_.get())
469 else if (&text_editor == start_position_.get())
471}
472
473void FileSourceOverlay::textEditorFocusLost(TextEditor& text_editor) {
474 if (&text_editor == window_size_.get())
476 else if (&text_editor == start_position_.get())
478}
479
480void FileSourceOverlay::positionMovedRelative(float ratio, bool mouse_up) {
481 if (file_source_ == nullptr)
482 return;
483
484 int num_samples = file_source_->buffer()->size;
485 float max_position = num_samples - file_source_->getWindowSize();
486 float position = 0.0f;
487 if (start_position_)
488 position = positionTextToSize(start_position_->getText());
489 position += ratio * max_position;
490 position = std::max(0.0f, std::min(max_position, position));
491 if (start_position_)
492 start_position_->setText(String(position, 1), false);
493
494 if (num_samples && current_frame_) {
496 audio_thumbnail_->setWindowPosition(position / num_samples);
497 }
498
499 notifyChanged(mouse_up);
500}
501
502void FileSourceOverlay::setTextEditorVisuals(TextEditor* text_editor, float height) {
503 text_editor->setColour(CaretComponent::caretColourId, findColour(Skin::kTextEditorCaret, true));
504 text_editor->setColour(TextEditor::textColourId, findColour(Skin::kBodyText, true));
505 text_editor->setColour(TextEditor::highlightedTextColourId, findColour(Skin::kBodyText, true));
506 text_editor->setColour(TextEditor::highlightColourId, findColour(Skin::kTextEditorSelection, true));
507
508 Font font = Fonts::instance()->monospace().withPointHeight(height * 0.6f);
509 text_editor->setFont(font);
510 text_editor->applyFontToAllText(font);
511 text_editor->resized();
512}
513
515 if (file_source_ == nullptr || window_size_ == nullptr)
516 return;
517
518 float window_size = windowTextToSize(window_size_->getText(), file_source_->buffer()->sample_rate);
519 if (window_size > 0.0f) {
520 file_source_->setWindowSize(window_size);
521 window_size_->setText(String(window_size, 1));
522
523 int num_samples = file_source_->buffer()->size;
524 if (num_samples)
525 audio_thumbnail_->setWindowSize(window_size / num_samples);
526
527 getParentComponent()->grabKeyboardFocus();
528 notifyChanged(true);
529 }
530}
531
533 if (file_source_ == nullptr || current_frame_ == nullptr)
534 return;
535
537 float position = 0.0f;
538 if (start_position_)
539 position = positionTextToSize(start_position_->getText());
540 if (position >= 0.0f) {
541 int num_samples = file_source_->buffer()->size;
542 if (num_samples) {
544 audio_thumbnail_->setWindowPosition(position / num_samples);
545 }
546
547 getParentComponent()->grabKeyboardFocus();
548 notifyChanged(true);
549 }
550}
551
553 current_frame_ = nullptr;
554 file_source_ = file_source;
555 audio_thumbnail_->setFileSource(file_source);
557}
558
560 if (start_position_ == nullptr)
561 return;
562
563 float max_position = file_source_->buffer()->size - file_source_->getWindowSize();
564 float position = positionTextToSize(start_position_->getText());
565 position = std::max(0.0f, std::min(position, max_position));
566 start_position_->setText(String(position, 1));
567}
AudioFormatManager format_manager_
Manages and recognizes different audio file formats.
Definition audio_file_drop_source.h:113
Interface for listening to mouse drag movements relative to the waveform.
Definition file_source_overlay.h:33
void resized() override
Resizes the component, adjusting the waveform display and line positions.
Definition file_source_overlay.cpp:73
static constexpr float kResolution
Definition file_source_overlay.h:46
void mouseUp(const MouseEvent &e) override
Definition file_source_overlay.cpp:208
void fileDragEnter(const StringArray &files, int x, int y) override
Called when files are dragged into this component.
Definition file_source_overlay.cpp:183
void fileDragExit(const StringArray &files) override
Called when files are dragged out of this component.
Definition file_source_overlay.cpp:187
void mouseDrag(const MouseEvent &e) override
Definition file_source_overlay.cpp:201
void clearAudioPositions()
Clears the currently displayed audio positions in the waveform.
Definition file_source_overlay.cpp:108
void audioFileLoaded(const File &file) override
Called when an audio file is loaded via drag-and-drop.
Definition file_source_overlay.cpp:170
float updateMousePosition(Point< float > position)
Updates the mouse position and returns the relative movement ratio.
Definition file_source_overlay.cpp:191
void setWindowValues()
Updates the display to reflect new window position and size.
Definition file_source_overlay.cpp:145
void mouseDown(const MouseEvent &e) override
Mouse event handlers for adjusting audio window start on drag.
Definition file_source_overlay.cpp:197
void setAudioPositions()
Updates the waveform visualization based on the current audio file data.
Definition file_source_overlay.cpp:116
AudioFileViewer()
Constructs an AudioFileViewer.
Definition file_source_overlay.cpp:54
force_inline void setWindowFade(double window_fade)
Definition file_source.h:120
double getWindowFade()
Gets the fade size for window blending.
Definition file_source.h:115
double getStartPosition()
Gets the current start position of the wave segment in samples.
Definition file_source.h:107
force_inline void setStartPosition(double start_position)
Definition file_source.h:119
A WavetableComponent that uses an external audio sample as its source.
Definition file_source.h:23
void loadBuffer(const float *buffer, int size, int sample_rate)
Loads audio data into the file source buffer.
Definition file_source.cpp:363
double getWindowSize()
Definition file_source.h:181
void detectPitch(int max_period=vital::WaveFrame::kWaveformSize)
Attempts to detect pitch in the loaded sample to determine window size automatically.
Definition file_source.cpp:376
FadeStyle
Different methods to blend or interpolate the loaded audio window into a wavetable frame.
Definition file_source.h:38
@ kNumFadeStyles
Definition file_source.h:43
void setNormalizeGain(bool normalize_gain)
Definition file_source.h:176
PhaseStyle getPhaseStyle()
Definition file_source.h:173
bool getNormalizeGain()
Definition file_source.h:174
void setFadeStyle(FadeStyle fade_style)
Definition file_source.h:178
void setPhaseStyle(PhaseStyle phase_style)
Definition file_source.cpp:337
const SampleBuffer * buffer() const
Definition file_source.h:171
void setWindowSize(double window_size)
Definition file_source.h:177
FileSourceKeyframe * getKeyframe(int index)
Definition file_source.cpp:332
PhaseStyle
Methods for handling phase information in the transformed wave.
Definition file_source.h:50
@ kNumPhaseStyles
Definition file_source.h:54
FadeStyle getFadeStyle()
Definition file_source.h:172
void textEditorFocusLost(TextEditor &text_editor) override
Called when text editors lose focus, updating values.
Definition file_source_overlay.cpp:473
void loadFilePressed()
Opens a file chooser to load an audio file into the FileSource.
Definition file_source_overlay.cpp:444
FileSourceOverlay()
Constructs a FileSourceOverlay.
Definition file_source_overlay.cpp:215
void sliderDragEnded(Slider *moved_slider) override
Called when slider drag ends, finalizing changes.
Definition file_source_overlay.cpp:422
std::unique_ptr< OpenGlTextEditor > start_position_
Definition file_source_overlay.h:286
virtual void setEditBounds(Rectangle< int > bounds) override
Sets the editing bounds for controls in this overlay.
Definition file_source_overlay.cpp:338
void positionMovedRelative(float ratio, bool mouse_up) override
Called by AudioFileViewer when the mouse moves relative to waveform position.
Definition file_source_overlay.cpp:480
void loadStartingPositionText()
Updates the FileSource's starting position from text input.
Definition file_source_overlay.cpp:532
std::unique_ptr< AudioFileViewer > audio_thumbnail_
Definition file_source_overlay.h:293
void loadFile(const File &file) override
Loads an audio file into the FileSource and updates UI.
Definition file_source_overlay.cpp:426
std::unique_ptr< OpenGlTextEditor > window_size_
Definition file_source_overlay.h:287
void audioFileLoaded(const File &file) override
Called when an audio file is loaded (via drag-drop or load button).
Definition file_source_overlay.cpp:462
void setFileSource(FileSource *file_source)
Sets the FileSource this overlay edits.
Definition file_source_overlay.cpp:552
std::unique_ptr< TextSelector > phase_style_
Definition file_source_overlay.h:291
void buttonClicked(Button *clicked_button) override
Handles button clicks (e.g., load button, normalize toggle).
Definition file_source_overlay.cpp:450
void clampStartingPosition()
Ensures the starting position is within valid range.
Definition file_source_overlay.cpp:559
FileSource::FileSourceKeyframe * current_frame_
Definition file_source_overlay.h:284
std::unique_ptr< SynthSlider > window_fade_
Definition file_source_overlay.h:288
FileSource * file_source_
Definition file_source_overlay.h:283
std::unique_ptr< OpenGlToggleButton > normalize_gain_
Definition file_source_overlay.h:292
void setTextEditorVisuals(TextEditor *text_editor, float height)
Applies visuals and font settings to a text editor.
Definition file_source_overlay.cpp:502
void textEditorReturnKeyPressed(TextEditor &text_editor) override
Called when return key is pressed in text editors (start position, window size).
Definition file_source_overlay.cpp:466
std::unique_ptr< TextButton > load_button_
Definition file_source_overlay.h:289
virtual void frameSelected(WavetableKeyframe *keyframe) override
Called when a keyframe is selected in the Wavetable.
Definition file_source_overlay.cpp:302
virtual ~FileSourceOverlay()
Definition file_source_overlay.cpp:300
void loadWindowSizeText()
Updates the FileSource's window size from text input.
Definition file_source_overlay.cpp:514
std::unique_ptr< TextSelector > fade_style_
Definition file_source_overlay.h:290
void sliderValueChanged(Slider *moved_slider) override
Responds to slider changes (window fade, fade style, phase style).
Definition file_source_overlay.cpp:404
Font & monospace()
Returns a reference to the monospace font.
Definition fonts.h:46
static Fonts * instance()
Gets the singleton instance of the Fonts class.
Definition fonts.h:52
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 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 setFillColor(Colour fill_color)
Sets a uniform fill color if only one color is needed.
Definition open_gl_line_renderer.h:127
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 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
force_inline void setBoostLeft(int index, float val)
Sets the left-side boost for a point, marking data as dirty.
Definition open_gl_line_renderer.h:84
void setActive(bool active)
Activates or deactivates rendering of this component.
Definition open_gl_multi_quad.h:331
void setTargetComponent(Component *target_component)
Sets a target component to help position the quads.
Definition open_gl_multi_quad.h:358
force_inline void setColor(Colour color)
Sets the base color for the quads.
Definition open_gl_multi_quad.h:102
Manages and provides access to vertex and fragment shaders used by the OpenGL rendering pipeline.
Definition shaders.h:19
@ kWidgetLineBoost
Definition skin.h:106
@ kWidgetPrimary1
Definition skin.h:165
@ kBodyText
Definition skin.h:133
@ kWidgetSecondary1
Definition skin.h:168
@ kOverlayScreen
Definition skin.h:140
@ kTextEditorSelection
Definition skin.h:203
@ kTextEditorCaret
Definition skin.h:202
Base class for all synthesizer sections, providing UI layout, painting, and interaction logic.
Definition synth_section.h:193
void addSlider(SynthSlider *slider, bool show=true, bool listen=true)
Definition synth_section.cpp:445
void addSubSection(SynthSection *section, bool show=true)
Adds a subsection (another SynthSection) as a child.
Definition synth_section.cpp:457
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
void addOpenGlComponent(OpenGlComponent *open_gl_component, bool to_beginning=false)
Definition synth_section.cpp:489
static TextLookAndFeel * instance()
Singleton instance access.
Definition text_look_and_feel.h:106
static int noteToMidiKey(const String &note)
Converts a note name (e.g. "A4") to a MIDI key number.
Definition tuning.cpp:99
void addTitle(const std::string &title)
Adds a title string for the next control section.
Definition wavetable_component_overlay.h:94
void addLine(int position)
Adds a vertical line divider at the given position.
Definition wavetable_component_overlay.h:88
void clearTitles()
Clears all control section titles.
Definition wavetable_component_overlay.h:82
void clearLines()
Clears all line divider positions.
Definition wavetable_component_overlay.h:77
A base overlay component for editing and interacting with a wavetable component's parameters.
Definition wavetable_component_overlay.h:22
void setControlsWidth(int width)
Sets the total width for controls in the overlay.
Definition wavetable_component_overlay.h:267
ControlsBackground controls_background_
Definition wavetable_component_overlay.h:300
virtual void setEditBounds(Rectangle< int > bounds)
Sets the editing bounds within which controls and titles are placed.
Definition wavetable_component_overlay.cpp:67
static constexpr float kTitleHeightRatio
Definition wavetable_component_overlay.h:32
int getPadding()
Gets the current padding value.
Definition wavetable_component_overlay.h:248
void notifyChanged(bool mouse_up)
Notifies listeners that a change has occurred to the frame.
Definition wavetable_component_overlay.cpp:86
Represents a single state of a waveform at a specific position in a wavetable.
Definition wavetable_keyframe.h:35
int index()
Gets the index of this keyframe within its owner component.
Definition wavetable_keyframe.cpp:32
WavetableComponent * owner()
Gets the WavetableComponent that owns this keyframe.
Definition wavetable_keyframe.h:152
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 midiNoteToFrequency(poly_float value)
Converts a MIDI note to a frequency (vectorized).
Definition poly_utils.h:123
constexpr int kMidiSize
MIDI note count (0-127).
Definition common.h:44
constexpr mono_float kPi
Pi constant.
Definition common.h:36
Declares the SampleViewer class that displays and animates a waveform sample.
A simple structure holding a buffer of samples loaded from the file source.
Definition file_source.h:60
int size
Number of samples in the buffer.
Definition file_source.h:63
int sample_rate
Sample rate of the audio data.
Definition file_source.h:64
std::unique_ptr< float[]> data
Pointer to raw audio data.
Definition file_source.h:62