Krotos Modules 3
Loading...
Searching...
No Matches
WaveformViewer.cpp
Go to the documentation of this file.
1#include "WaveformViewer.h"
2#include "KrotosBinaryData.h"
3
4namespace krotos
5{
6 WaveformViewer::WaveformViewer(Colour waveformColour) : m_waveformColour(waveformColour)
7 {
8 m_formatManager = std::make_unique<AudioFormatManager>();
9 m_formatManager->registerBasicFormats();
10
11 const int downsampleFactor = 1;
12 m_thumbnailCache = std::make_unique<AudioThumbnailCache>(2);
13 m_thumbnail = std::make_unique<AudioThumbnail>(downsampleFactor, *m_formatManager, *m_thumbnailCache);
14
15 m_titleLabel.setJustificationType(Justification::centredTop);
16 m_titleLabel.setFont(12);
17 addAndMakeVisible(m_titleLabel);
18
19 // Load the backdrop image resource
20 int dataSizeBytes = 0;
21 auto resource =
22 KrotosBinaryData::getNamedResource(m_layout.waveformAreaBackdropImageName.toUTF8(), dataSizeBytes);
23 m_waveformAreaBackdropImage = Drawable::createFromImageData(resource, dataSizeBytes);
24
25 resource = KrotosBinaryData::getNamedResource(m_layout.addIconImageName.toUTF8(), dataSizeBytes);
26 m_addIconImage = Drawable::createFromImageData(resource, dataSizeBytes);
27
28 // The backdrop could be added here using addAndMakeVisible(), but would be
29 // drawn after the paint() method is called, obscuring the audio thumbnail.
30 // For that reason it is drawn in from the paint() method instead
31 }
32
34
36
37 void WaveformViewer::paint(Graphics& g)
38 {
39 if (!isEnabled())
40 return;
41
43
44 // Draw in the backdrop image
45 m_waveformAreaBackdropImage->drawWithin(g, getLocalBounds().toFloat(), RectanglePlacement::centred, 1.f);
46
47 // Is there a thumbnail to draw ?
48 if (m_thumbnail != nullptr && m_thumbnail->getNumSamplesFinished() > 0)
49 {
50 // Draw background grid
51 if (m_drawGrid)
52 {
53 DrawingHelper::drawBackgroundGridNoBackground(g, 10, getLocalBounds());
54 }
55
56 auto zoomRange = getHorizontalRange();
57 double audioFileDuration = m_thumbnail->getTotalLength();
58 double startTimeSeconds = zoomRange.getStart() * audioFileDuration;
59 double endTimeSeconds = zoomRange.getEnd() * audioFileDuration;
60 float verticalZoom = 1.0f;
61 g.setColour(m_waveformColour);
62 m_thumbnail->drawChannels(g, getLocalBounds(), startTimeSeconds, endTimeSeconds, verticalZoom);
63
64 // Show file name if enabled
66 {
67 g.setColour(Colours::white);
68 g.setFont(12);
69 g.drawText(m_fileName, 2, 2, 250, 12, Justification::left);
70 }
71 }
72 else // Draw "drop a file" text
73 {
74 // Set droptext colour
75 const Colour gentleRed(165, 79, 64);
76 m_dropText.containsIgnoreCase("fail") ? g.setColour(gentleRed)
77 : g.setColour(Colours::white.withAlpha(opacity));
78
79 // Set droptext font
80 g.setFont(m_layout.dropTextFont.withHorizontalScale(m_layout.dropTextHorizontalScaleFactor));
81
82 // Draw droptext
83 g.drawFittedText(m_dropText, m_layout.dropTextArea, Justification::centredLeft, 2);
84
85 // Draw +Icon
86 m_addIconImage->drawWithin(g, m_layout.plusButtonArea.toFloat(), RectanglePlacement::centred, opacity);
87 }
88
90 {
91 const Colour hoverGreen(186, 205, 127);
92 g.setColour(hoverGreen.withAlpha(0.15f));
93 g.fillAll();
94 }
95 }
96
97 void WaveformViewer::resized() { m_titleLabel.setBounds(0, 5, getWidth(), 20); }
98
99 void WaveformViewer::updateWaveformView(const AudioBuffer<float>& newAudio)
100 {
101 if (newAudio.getNumSamples())
102 {
103 updateWaveformThumbnail(newAudio);
104 }
105 else
106 {
107 DBG("the test sample file did not open");
108 }
109 }
110
111 void WaveformViewer::updateWaveformViewInterpolateBuffers(float gainSliderValue, const AudioBuffer<float>& buffer1,
112 const AudioBuffer<float>& buffer2, float samplePosition)
113 {
114 int len = static_cast<int>(m_fixedSampleRate);
115 AudioBuffer<float> monoAudioBuffer{1, len};
116
117 float gain1 = gainSliderValue;
118 float gain2 = -1.0f * gainSliderValue + 1.0f;
119
120 for (int sampleNum = 0; sampleNum < len; ++sampleNum)
121 {
122 float sample1 = buffer1.getSample(0, int(samplePosition));
123 float sample2 = buffer2.getSample(0, int(samplePosition));
124 samplePosition += 1.0f;
125
126 if (samplePosition >= m_fixedSampleRate)
127 samplePosition = 0.0f;
128
129 monoAudioBuffer.setSample(0, sampleNum, gain2 * sample1 + gain1 * sample2);
130 }
131
132 updateWaveformThumbnail(monoAudioBuffer);
133 repaint();
134 }
135
137 {
138 m_thumbnailCache->clear();
139 m_thumbnail->clear();
140
141 m_fileName.clear();
142
143 repaint();
144 }
145
146 void WaveformViewer::waveformZoomed(const AudioBuffer<float>& audioBuffer, int startSample, int numsamples) const
147 {
148 m_thumbnail->reset(int(m_wavReader->numChannels), m_wavReader->sampleRate, audioBuffer.getNumSamples());
149 m_thumbnail->addBlock(0, audioBuffer, startSample, numsamples);
150 }
151
152 void WaveformViewer::setWaveformColour(Colour waveformColour) { m_waveformColour = waveformColour; }
153
154 void WaveformViewer::setTitle(const String& title) { m_titleLabel.setText(title, dontSendNotification); }
155
156 void WaveformViewer::setDropText(const String& newText) { m_dropText = newText; }
157
158 void WaveformViewer::setDrawGrid(bool drawGrid) { m_drawGrid = drawGrid; }
159
160 void WaveformViewer::setShowFileName(bool showFileName) { m_showFileName = showFileName; }
161
163
165
167
168 bool WaveformViewer::matchesExpression(const String& /*expression*/, const String& /*stringToTest*/)
169 {
170 /* SANTODO reinstate
171 try
172 {
173 std::regex reg(expression.toStdString());
174
175 return std::regex_search(stringToTest.toStdString(), reg);
176 }
177 catch (std::regex_error e)
178 {
179 DBG(e.what());
180
181 return false;
182 }*/
183
184 return true;
185 }
186
187 void WaveformViewer::setRegexFileFilter(const String& newExpression) { m_regexFileFilter = newExpression; }
188
189 bool WaveformViewer::soundFileTypeIsValid(std::string /*fileName*/)
190 {
191 /* SANTODO: reinstate
192 std::regex acceptedExtensions(".wav|.aif|.aiff|.ogg|.flac", std::regex_constants::icase);
193 return std::regex_search(fileName.begin(), fileName.end(), acceptedExtensions);*/
194
195 return true;
196 }
197
198 Array<File> WaveformViewer::getExtendedFilePaths(const StringArray& files)
199 {
200 Array<File> referencedFiles;
201
202 if ((m_limitToSingleDroppedItem && files.size() != 1) || files.size() < 1)
203 return referencedFiles;
204
205 for (auto f : files)
206 {
207 File file{f};
208
209 if (file.isDirectory())
210 referencedFiles.addArray(
211 file.findChildFiles(File::findFiles, true, "*.wav;*.aif;*.aiff;*.flac;*.ogg;*.kaf"));
212 else if (soundFileTypeIsValid(f.toStdString()))
213 referencedFiles.add(file);
214 }
215
216 if (m_regexFileFilter == "" || referencedFiles.size() <= 1)
217 return referencedFiles;
218
219 Array<File> filteredFiles;
220
221 for (auto& fl : referencedFiles)
222 if (matchesExpression(m_regexFileFilter, fl.getFileName()))
223 filteredFiles.add(fl);
224
225 return filteredFiles;
226 }
227
228 void WaveformViewer::setHoverState(bool newState) { m_mouseHover = newState; }
229
230 bool WaveformViewer::isInterestedInFileDrag(const StringArray& files)
231 {
233 {
234 Array<File> referencedFiles = getExtendedFilePaths(files);
235 m_numDraggedFilesHovering = referencedFiles.size();
236
237 return m_numDraggedFilesHovering > 0;
238 }
239
240 if (files.size() != 1)
241 return false;
242
243 return soundFileTypeIsValid(files[0].toStdString());
244 }
245
246 void WaveformViewer::fileDragEnter(const StringArray& files, int /*x*/, int /*y*/)
247 {
248 // if the waveform viewer is disabled do nothing
249 if (!isEnabled())
250 {
251 return;
252 }
253
254 if (isInterestedInFileDrag(files))
255 {
257 repaint();
258 }
259 }
260
261 void WaveformViewer::fileDragExit(const StringArray& /*files*/)
262 {
264 {
266 repaint();
267 }
268 }
269
270 void WaveformViewer::updateWaveformThumbnail(const AudioBuffer<float>& audioBuffer)
271 {
272 m_thumbnail->reset(audioBuffer.getNumChannels(), m_fixedSampleRate, audioBuffer.getNumSamples());
273
274 m_thumbnail->addBlock(0, audioBuffer, 0, audioBuffer.getNumSamples());
275 }
276
277 void WaveformViewer::mixStereoBufferToMono(const AudioBuffer<float>& stereo, AudioBuffer<float>& mono) const
278 {
279 mono.setSize(1, int(m_wavReader->lengthInSamples));
280 mono.copyFrom(0, 0, stereo, 0, 0, int(m_wavReader->lengthInSamples));
281 mono.addFrom(0, 0, stereo, 1, 0, int(m_wavReader->lengthInSamples));
282 mono.applyGain(0, int(m_wavReader->lengthInSamples), 0.5f);
283 }
284} // namespace krotos
static void drawBackgroundGridNoBackground(Graphics &g, int boxWidth, const Rectangle< int > &bounds)
Definition krotosDrawingHelper.cpp:22
Definition WaveformViewer.h:16
static constexpr float m_fixedSampleRate
Definition WaveformViewer.h:116
void setLimitToSingleDroppedItem(bool val)
Definition WaveformViewer.cpp:166
void addListener(WaveformViewer::Listener *Listener)
Definition WaveformViewer.cpp:33
void removeListener(WaveformViewer::Listener *Listener)
Definition WaveformViewer.cpp:35
void paint(Graphics &g) override
Definition WaveformViewer.cpp:37
String m_regexFileFilter
Definition WaveformViewer.h:107
void fileDragExit(const StringArray &files)
Definition WaveformViewer.cpp:261
bool m_showFileName
Definition WaveformViewer.h:128
std::unique_ptr< AudioThumbnailCache > m_thumbnailCache
Definition WaveformViewer.h:121
WaveformViewer(Colour waveformColour=Colours::white)
Definition WaveformViewer.cpp:6
void setUseExtendedFilePaths(bool val)
Definition WaveformViewer.cpp:164
bool m_draggedItemIsHovering
Definition WaveformViewer.h:130
void mixStereoBufferToMono(const AudioBuffer< float > &stereo, AudioBuffer< float > &mono) const
Definition WaveformViewer.cpp:277
bool m_mouseHover
Definition WaveformViewer.h:99
void updateWaveformViewInterpolateBuffers(float gainSliderValue, const AudioBuffer< float > &buffer1, const AudioBuffer< float > &buffer2, float samplePosition=0.0f)
Definition WaveformViewer.cpp:111
void setDropText(const String &newText)
Definition WaveformViewer.cpp:156
bool m_dragBorderShouldShow
Definition WaveformViewer.h:129
bool matchesExpression(const String &expression, const String &stringToTest)
Definition WaveformViewer.cpp:168
void setDrawGrid(bool drawGrid)
Definition WaveformViewer.cpp:158
Label m_titleLabel
Definition WaveformViewer.h:124
void setRegexFileFilter(const String &newExpression)
Definition WaveformViewer.cpp:187
void resized() override
Definition WaveformViewer.cpp:97
std::unique_ptr< AudioFormatManager > m_formatManager
Definition WaveformViewer.h:119
void setWaveformColour(Colour waveformColour)
Definition WaveformViewer.cpp:152
int m_numDraggedFilesHovering
Definition WaveformViewer.h:133
ListenerList< WaveformViewer::Listener > m_listeners
Definition WaveformViewer.h:106
Colour m_waveformColour
Definition WaveformViewer.h:110
bool m_useExtendedFilePaths
Definition WaveformViewer.h:132
Array< File > getExtendedFilePaths(const StringArray &files)
Definition WaveformViewer.cpp:198
bool m_drawGrid
Definition WaveformViewer.h:125
std::unique_ptr< Drawable > m_addIconImage
Definition WaveformViewer.h:101
void fileDragEnter(const StringArray &files, int x, int y)
Definition WaveformViewer.cpp:246
void setTitle(const String &title)
Definition WaveformViewer.cpp:154
void setShowFileName(bool showFileName)
Definition WaveformViewer.cpp:160
bool isInterestedInFileDrag(const StringArray &files)
Definition WaveformViewer.cpp:230
void setHoverState(bool newState)
Definition WaveformViewer.cpp:228
void updateWaveformThumbnail(const AudioBuffer< float > &monoAudioBuffer)
Definition WaveformViewer.cpp:270
virtual void updateWaveformView(const AudioBuffer< float > &newAudio)
Definition WaveformViewer.cpp:99
std::unique_ptr< Drawable > m_waveformAreaBackdropImage
Definition WaveformViewer.h:100
void clear()
Definition WaveformViewer.cpp:136
std::unique_ptr< AudioThumbnail > m_thumbnail
Definition WaveformViewer.h:122
bool soundFileTypeIsValid(std::string fileName)
Definition WaveformViewer.cpp:189
String m_fileName
Definition WaveformViewer.h:113
String m_dropText
Definition WaveformViewer.h:114
void waveformZoomed(const AudioBuffer< float > &audioBuffer, int startSample, int numsamples) const
Definition WaveformViewer.cpp:146
bool m_limitToSingleDroppedItem
Definition WaveformViewer.h:134
void setShowBorderOnDragHover(bool showBorder)
Definition WaveformViewer.cpp:162
struct krotos::WaveformViewer::Layout m_layout
std::unique_ptr< AudioFormatReader > m_wavReader
Definition WaveformViewer.h:120
Range< float > getHorizontalRange() const
Definition ZoomableComponent.cpp:3
Definition AirAbsorptionFilter.cpp:2
const Rectangle< int > dropTextArea
Definition WaveformViewer.h:88
const float dropTextOpacityHover
Definition WaveformViewer.h:94
const String waveformAreaBackdropImageName
Definition WaveformViewer.h:86
const float dropTextHorizontalScaleFactor
Definition WaveformViewer.h:91
const Rectangle< int > plusButtonArea
Definition WaveformViewer.h:96
const Font dropTextFont
Definition WaveformViewer.h:92
const float dropTextOpacityDefault
Definition WaveformViewer.h:93
const String addIconImageName
Definition WaveformViewer.h:87