Audacity 3.2.0
VampEffect.cpp
Go to the documentation of this file.
1/**********************************************************************
2
3 Audacity: A Digital Audio Editor
4
5 VampEffect.cpp
6
7 Chris Cannam, with heavy borrowing from LadspaEffect.cpp
8
9 Vamp is an audio analysis and feature extraction plugin API.
10 http://www.vamp-plugins.org/
11
12**********************************************************************/
13
14
15
16#if defined(USE_VAMP)
17#include "VampEffect.h"
18
19#include <vamp-hostsdk/Plugin.h>
20#include <vamp-hostsdk/PluginChannelAdapter.h>
21#include <vamp-hostsdk/PluginInputDomainAdapter.h>
22
23#include <wx/wxprec.h>
24#include <wx/button.h>
25#include <wx/checkbox.h>
26#include <wx/choice.h>
27#include <wx/combobox.h>
28#include <wx/sizer.h>
29#include <wx/slider.h>
30#include <wx/statbox.h>
31#include <wx/stattext.h>
32#include <wx/textctrl.h>
33#include <wx/tokenzr.h>
34#include <wx/intl.h>
35#include <wx/scrolwin.h>
36#include <wx/version.h>
37
38
39#include "../../ShuttleGui.h"
40#include "../../widgets/valnum.h"
41#include "../../widgets/AudacityMessageBox.h"
42
43#include "../../LabelTrack.h"
44#include "../../WaveTrack.h"
45
46enum
47{
48 ID_Program = 10000,
49 ID_Sliders = 11000,
50 ID_Choices = 12000,
51 ID_Texts = 13000,
52 ID_Toggles = 14000,
53};
54
56//
57// VampEffect
58//
60
61BEGIN_EVENT_TABLE(VampEffect, wxEvtHandler)
62 EVT_SLIDER(wxID_ANY, VampEffect::OnSlider)
63 EVT_TEXT(wxID_ANY, VampEffect::OnTextCtrl)
64 EVT_CHECKBOX(wxID_ANY, VampEffect::OnCheckBox)
65 EVT_CHOICE(wxID_ANY, VampEffect::OnChoice)
67
68VampEffect::VampEffect(std::unique_ptr<Vamp::Plugin> &&plugin,
69 const PluginPath & path,
70 int output,
71 bool hasParameters)
72: mPlugin(std::move(plugin)),
73 mPath(path),
74 mOutput(output),
75 mHasParameters(hasParameters),
76 mRate(0)
77{
78 mKey = mPath.BeforeLast(wxT('/')).ToUTF8();
79 mName = mPath.AfterLast(wxT('/'));
80}
81
83{
84}
85
86// ============================================================================
87// ComponentInterface implementation
88// ============================================================================
89
91{
92 return mPath;
93}
94
96{
97 return mName;
98}
99
101{
102 return { wxString::FromUTF8(mPlugin->getMaker().c_str()) };
103}
104
106{
107 return wxString::Format(wxT("%d"), mPlugin->getPluginVersion());
108}
109
111{
112 return Verbatim(
113 wxString::FromUTF8(mPlugin->getCopyright().c_str()) );
114}
115
116// ============================================================================
117// EffectDefinitionInterface implementation
118// ============================================================================
119
121{
122 return EffectTypeAnalyze;
123}
124
126{
127 return VAMPEFFECTS_FAMILY;
128}
129
131{
132 return mHasParameters;
133}
134
136{
137 return false;
138}
139
141{
142 return mPlugin->getMaxChannelCount();
143}
144
146 const EffectSettings &, CommandParameters & parms) const
147{
148 for (size_t p = 0, paramCount = mParameters.size(); p < paramCount; p++)
149 {
150 wxString key = wxString::FromUTF8(mParameters[p].identifier.c_str());
151 float value = mPlugin->getParameter(mParameters[p].identifier);
152 float lower = mParameters[p].minValue;
153 float upper = mParameters[p].maxValue;
154
155 if (mParameters[p].isQuantized &&
156 mParameters[p].quantizeStep == 1.0 &&
157 lower == 0.0 &&
158 upper == 1.0)
159 {
160 bool val = value > 0.5;
161
162 parms.Write(key, val);
163 }
164 else if (mParameters[p].isQuantized &&
165 mParameters[p].quantizeStep == 1.0 &&
166 !mParameters[p].valueNames.empty())
167 {
168 std::vector<EnumValueSymbol> choices;
169 int val = 0;
170
171 for (size_t i = 0, choiceCount = mParameters[p].valueNames.size(); i < choiceCount; i++)
172 {
173 wxString choice = wxString::FromUTF8(mParameters[p].valueNames[i].c_str());
174 if (size_t(value - mParameters[p].minValue + 0.5) == i)
175 {
176 val = i;
177 }
178 choices.push_back(choice);
179 }
180
181 parms.WriteEnum(key, val, choices.data(), choices.size());
182 }
183 else
184 {
185 parms.Write(key, value);
186 }
187 }
188
189 return true;
190}
191
193 const CommandParameters & parms, EffectSettings &settings) const
194{
195 // First pass verifies values
196 for (size_t p = 0, paramCount = mParameters.size(); p < paramCount; p++)
197 {
198 wxString key = wxString::FromUTF8(mParameters[p].identifier.c_str());
199 float lower = mParameters[p].minValue;
200 float upper = mParameters[p].maxValue;
201 bool good = false;
202
203 if (mParameters[p].isQuantized &&
204 mParameters[p].quantizeStep == 1.0 &&
205 lower == 0.0 &&
206 upper == 1.0)
207 {
208 bool val;
209
210 good = parms.Read(key, &val);
211 }
212 else if (mParameters[p].isQuantized &&
213 mParameters[p].quantizeStep == 1.0 &&
214 !mParameters[p].valueNames.empty())
215 {
216 std::vector<EnumValueSymbol> choices;
217 int val;
218
219 for (size_t i = 0, choiceCount = mParameters[p].valueNames.size(); i < choiceCount; i++)
220 {
221 wxString choice = wxString::FromUTF8(mParameters[p].valueNames[i].c_str());
222 choices.push_back(choice);
223 }
224
225 good = parms.ReadEnum(key, &val, choices.data(), choices.size()) && val != wxNOT_FOUND;
226 }
227 else
228 {
229 double val;
230
231 good = parms.Read(key, &val) && val >= lower && val <= upper;
232 }
233
234 if (!good)
235 {
236 return false;
237 }
238 }
239
240 // Second pass sets the variables
241 for (size_t p = 0, paramCount = mParameters.size(); p < paramCount; p++)
242 {
243 wxString key = wxString::FromUTF8(mParameters[p].identifier.c_str());
244 float lower = mParameters[p].minValue;
245 float upper = mParameters[p].maxValue;
246
247 if (mParameters[p].isQuantized &&
248 mParameters[p].quantizeStep == 1.0 &&
249 lower == 0.0 &&
250 upper == 1.0)
251 {
252 bool val;
253
254 parms.Read(key, &val);
255
256 mPlugin->setParameter(mParameters[p].identifier, val ? upper : lower);
257 }
258 else if (mParameters[p].isQuantized &&
259 mParameters[p].quantizeStep == 1.0 &&
260 !mParameters[p].valueNames.empty())
261 {
262 std::vector<EnumValueSymbol> choices;
263 int val = 0;
264
265 for (size_t i = 0, choiceCount = mParameters[p].valueNames.size(); i < choiceCount; i++)
266 {
267 wxString choice = wxString::FromUTF8(mParameters[p].valueNames[i].c_str());
268 choices.push_back(choice);
269 }
270
271 parms.ReadEnum(key, &val, choices.data(), choices.size());
272
273 mPlugin->setParameter(mParameters[p].identifier, (float) val);
274 }
275 else
276 {
277 double val;
278
279 parms.Read(key, &val);
280
281 if (mParameters[p].isQuantized)
282 {
283 float qs = mParameters[p].quantizeStep;
284
285 if (qs != 0.0)
286 {
287 val = (int)((val - lower) / qs + 0.5) * qs + lower;
288 }
289 }
290
291 mPlugin->setParameter(mParameters[p].identifier, val);
292 }
293 }
294
295 return true;
296}
297
299{
300 mRate = 0.0;
301
302 // PRL: this loop checked that channels of a track have the same rate,
303 // but there was no check that all tracks have one rate, and only the first
304 // is remembered in mRate. Is that correct?
305
306 for (auto leader : inputTracks()->Leaders<const WaveTrack>()) {
307 auto channelGroup = TrackList::Channels( leader );
308 auto rate = (*channelGroup.first++) -> GetRate();
309 for(auto channel : channelGroup) {
310 if (rate != channel->GetRate())
311 // PRL: Track rate might not match individual clip rates.
312 // So is this check not adequate?
313 {
314 // TODO: more-than-two-channels-message
316 XO(
317"Sorry, Vamp Plug-ins cannot be run on stereo tracks where the individual channels of the track do not match.") );
318 return false;
319 }
320 }
321 if (mRate == 0.0)
322 mRate = rate;
323 }
324
325 if (mRate <= 0.0)
326 {
328 }
329
330 // The plugin must be reloaded to allow changing parameters
331
332 Vamp::HostExt::PluginLoader *loader = Vamp::HostExt::PluginLoader::getInstance();
333 mPlugin.reset(loader->loadPlugin(mKey, mRate, Vamp::HostExt::PluginLoader::ADAPT_ALL));
334 if (!mPlugin)
335 {
336 Effect::MessageBox( XO("Sorry, failed to load Vamp Plug-in.") );
337 return false;
338 }
339
340 return true;
341}
342
344{
345 if (!mPlugin)
346 {
347 return false;
348 }
349
350 int count = 0;
351
352 bool multiple = false;
353 unsigned prevTrackChannels = 0;
354
355 if (GetNumWaveGroups() > 1)
356 {
357 // if there is another track beyond this one and any linked one,
358 // then we're processing more than one track. That means we
359 // should use the originating track name in each NEW label
360 // track's name, to make clear which is which
361 multiple = true;
362 }
363
364 std::vector<std::shared_ptr<Effect::AddedAnalysisTrack>> addedTracks;
365
366 for (auto leader : inputTracks()->Leaders<const WaveTrack>())
367 {
368 auto channelGroup = TrackList::Channels(leader);
369 auto left = *channelGroup.first++;
370
371 unsigned channels = 1;
372
373 // channelGroup now contains all but the first channel
374 const WaveTrack *right =
375 channelGroup.size() ? *channelGroup.first++ : nullptr;
376 if (right)
377 channels = 2;
378
379 sampleCount start = 0;
380 sampleCount len = 0;
381 GetBounds(*left, right, &start, &len);
382
383 // TODO: more-than-two-channels
384
385 size_t step = mPlugin->getPreferredStepSize();
386 size_t block = mPlugin->getPreferredBlockSize();
387
388 bool initialiseRequired = true;
389
390 if (block == 0)
391 {
392 if (step != 0)
393 {
394 block = step;
395 }
396 else
397 {
398 block = 1024;
399 }
400 }
401
402 if (step == 0)
403 {
404 step = block;
405 }
406
407 if (prevTrackChannels > 0)
408 {
409 // Plugin has already been initialised, so if the number of
410 // channels remains the same, we only need to do a reset.
411 // Otherwise we need to re-construct the whole plugin,
412 // because a Vamp plugin can't be re-initialised.
413 if (prevTrackChannels == channels)
414 {
415 mPlugin->reset();
416 initialiseRequired = false;
417 }
418 else
419 {
421 Init();
422 }
423 }
424
425 if (initialiseRequired)
426 {
427 if (!mPlugin->initialise(channels, step, block))
428 {
430 XO("Sorry, Vamp Plug-in failed to initialize.") );
431 return false;
432 }
433 }
434
435 const auto effectName = GetSymbol().Translation();
436 addedTracks.push_back(AddAnalysisTrack(
437 multiple
438 ? wxString::Format( _("%s: %s"), left->GetName(), effectName )
439 : effectName
440 ));
441 LabelTrack *ltrack = addedTracks.back()->get();
442
443 FloatBuffers data{ channels, block };
444
445 auto originalLen = len;
446
447 auto pos = start;
448
449 while (len != 0)
450 {
451 const auto request = limitSampleBufferSize( block, len );
452
453 if (left)
454 {
455 left->GetFloats(data[0].get(), pos, request);
456 }
457
458 if (right)
459 {
460 right->GetFloats(data[1].get(), pos, request);
461 }
462
463 if (request < block)
464 {
465 for (unsigned int c = 0; c < channels; ++c)
466 {
467 for (decltype(block) i = request; i < block; ++i)
468 {
469 data[c][i] = 0.f;
470 }
471 }
472 }
473
474 // UNSAFE_SAMPLE_COUNT_TRUNCATION
475 // Truncation in case of very long tracks!
476 Vamp::RealTime timestamp = Vamp::RealTime::frame2RealTime(
477 long( pos.as_long_long() ),
478 (int)(mRate + 0.5)
479 );
480
481 Vamp::Plugin::FeatureSet features = mPlugin->process(
482 reinterpret_cast< float** >( data.get() ), timestamp);
483 AddFeatures(ltrack, features);
484
485 if (len > (int)step)
486 {
487 len -= step;
488 }
489 else
490 {
491 len = 0;
492 }
493
494 pos += step;
495
496 if (channels > 1)
497 {
498 if (TrackGroupProgress(count,
499 (pos - start).as_double() /
500 originalLen.as_double() ))
501 {
502 return false;
503 }
504 }
505 else
506 {
507 if (TrackProgress(count,
508 (pos - start).as_double() /
509 originalLen.as_double() ))
510 {
511 return false;
512 }
513 }
514 }
515
516 Vamp::Plugin::FeatureSet features = mPlugin->getRemainingFeatures();
517 AddFeatures(ltrack, features);
518
519 prevTrackChannels = channels;
520 }
521
522 // All completed without cancellation, so commit the addition of tracks now
523 for (auto &addedTrack : addedTracks)
524 addedTrack->Commit();
525
526 return true;
527}
528
529std::unique_ptr<EffectUIValidator> VampEffect::PopulateOrExchange(
531{
532 Vamp::Plugin::ProgramList programs = mPlugin->getPrograms();
533
534 mParameters = mPlugin->getParameterDescriptors();
535
536 auto count = mParameters.size();
537
538 mToggles.reinit( count );
539 mSliders.reinit( count );
540 mFields.reinit( count );
541 mLabels.reinit( count );
542 mChoices.reinit( count );
543 mValues.reinit( count );
544
545 wxScrolledWindow *scroller = S.Style(wxVSCROLL | wxTAB_TRAVERSAL)
546 .StartScroller(2);
547 {
548 S.StartStatic(XO("Plugin Settings"));
549 {
550 S.StartMultiColumn(5, wxEXPAND);
551 {
552 S.SetStretchyCol(3);
553
554 if (!programs.empty())
555 {
556 S.AddPrompt(XXO("Program"));
557
558 S.Id(ID_Program);
559 mProgram = S.Name(XO("Program"))
560 .MinSize( { -1, -1 } )
561 .Position(wxEXPAND | wxALIGN_CENTER_VERTICAL | wxALL)
562 .AddChoice( {},
563 [&]{
564 TranslatableStrings choices;
565 for (const auto &program : programs)
566 choices.push_back(
567 Verbatim(wxString::FromUTF8(program.c_str())));
568 return choices;
569 }(),
570 Verbatim( wxString::FromUTF8(mPlugin->getCurrentProgram().c_str()) )
571 );
572
573 S.AddSpace(1, 1);
574 S.AddSpace(1, 1);
575 S.AddSpace(1, 1);
576 }
577
578 for (size_t p = 0; p < count; p++)
579 {
580 wxString tip = wxString::FromUTF8(mParameters[p].description.c_str());
581 wxString unit = wxString::FromUTF8(mParameters[p].unit.c_str());
582
583 float value = mPlugin->getParameter(mParameters[p].identifier);
584
585 mToggles[p] = NULL;
586 mChoices[p] = NULL;
587 mSliders[p] = NULL;
588 mFields[p] = NULL;
589 mValues[p] = 0.0;
590
591 wxString labelText = wxString::FromUTF8(mParameters[p].name.c_str());
592 if (!unit.empty())
593 {
594 labelText += wxT(" (") + unit + wxT(")");
595 }
596 /* i18n-hint: An item name introducing a value, which is not part of the string but
597 appears in a following text box window; translate with appropriate punctuation */
598 S.AddPrompt(XXO("%s:").Format( labelText ));
599
600 if (mParameters[p].isQuantized &&
601 mParameters[p].quantizeStep == 1.0 &&
602 mParameters[p].minValue == 0.0 &&
603 mParameters[p].maxValue == 1.0)
604 {
605 S.Id(ID_Toggles + p);
606 mToggles[p] = S.ToolTip( Verbatim( tip ) )
607 .Name( Verbatim( labelText ) )
608 .Position(wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL)
609 .AddCheckBox( {},
610 value > 0.5 );
611
612 S.AddSpace(1, 1);
613 S.AddSpace(1, 1);
614 S.AddSpace(1, 1);
615
616 }
617 else if (mParameters[p].isQuantized &&
618 mParameters[p].quantizeStep == 1.0 &&
619 !mParameters[p].valueNames.empty())
620 {
621 TranslatableStrings choices;
622 int selected = -1;
623
624 for (size_t i = 0, cnt = mParameters[p].valueNames.size(); i < cnt; i++)
625 {
626 wxString choice = wxString::FromUTF8(mParameters[p].valueNames[i].c_str());
627 if (size_t(value - mParameters[p].minValue + 0.5) == i)
628 {
629 selected = i;
630 }
631 choices.push_back( Verbatim( choice ) );
632 }
633
634 S.Id(ID_Choices + p);
635 mChoices[p] = S.ToolTip( Verbatim( tip ) )
636 .Name( Verbatim( labelText ) )
637 .Position(wxEXPAND | wxALIGN_CENTER_VERTICAL | wxALL)
638 .MinSize( { -1, -1 } )
639 .AddChoice( {}, choices, selected );
640
641 S.AddSpace(1, 1);
642 S.AddSpace(1, 1);
643 S.AddSpace(1, 1);
644 }
645 else
646 {
647 mValues[p] = value;
648
649 float range = mParameters[p].maxValue - mParameters[p].minValue;
650
651 S.Id(ID_Texts + p);
652 mFields[p] = S.ToolTip( Verbatim( tip ) )
653 .Name( Verbatim( labelText ) )
654 .Position(wxALIGN_CENTER_VERTICAL | wxALL)
655 .Validator<FloatingPointValidator<float>>(
656 6, &mValues[p],
657 (range < 10
658 ? NumValidatorStyle::THREE_TRAILING_ZEROES
659 : range < 100
660 ? NumValidatorStyle::TWO_TRAILING_ZEROES
661 : NumValidatorStyle::ONE_TRAILING_ZERO),
662 mParameters[p].minValue, mParameters[p].maxValue)
663 .AddTextBox( {}, wxT(""), 12);
664
665 wxString str = Internat::ToDisplayString(mParameters[p].minValue);
666 S.AddPrompt( Verbatim( str ) );
667
668 S.Id(ID_Sliders + p);
669 mSliders[p] = S.ToolTip( Verbatim( tip ) )
670 .Name( Verbatim( labelText ) )
671 .Style(wxSL_HORIZONTAL)
672 .MinSize( { 150, -1 } )
673 .AddSlider( {}, 0, 1000, 0);
674
676 S.AddUnits( Verbatim( str ) );
677 }
678 }
679 }
680 S.EndMultiColumn();
681 }
682 S.EndStatic();
683 }
684 S.EndScroller();
685
686 scroller->SetScrollRate(0, 20);
687
688 return nullptr;
689}
690
692{
694 return true;
695}
696
697// VampEffect implementation
698
700 Vamp::Plugin::FeatureSet &features)
701{
702 for (Vamp::Plugin::FeatureList::iterator fli = features[mOutput].begin();
703 fli != features[mOutput].end(); ++fli)
704 {
705 Vamp::RealTime ftime0 = fli->timestamp;
706 double ltime0 = ftime0.sec + (double(ftime0.nsec) / 1000000000.0);
707
708 Vamp::RealTime ftime1 = ftime0;
709 if (fli->hasDuration) ftime1 = ftime0 + fli->duration;
710 double ltime1 = ftime1.sec + (double(ftime1.nsec) / 1000000000.0);
711
712 wxString label = LAT1CTOWX(fli->label.c_str());
713 if (label == wxString())
714 {
715 if (fli->values.empty())
716 {
717 label = wxString::Format(LAT1CTOWX("%.3f"), ltime0);
718 }
719 else
720 {
721 label = wxString::Format(LAT1CTOWX("%.3f"), *fli->values.begin());
722 }
723 }
724
725 ltrack->AddLabel(SelectedRegion(ltime0, ltime1), label);
726 }
727}
728
730{
731 for (size_t p = 0, cnt = mParameters.size(); p < cnt; p++)
732 {
733 float value = mPlugin->getParameter(mParameters[p].identifier);
734
735 if (mParameters[p].isQuantized &&
736 mParameters[p].quantizeStep == 1.0 &&
737 mParameters[p].minValue == 0.0 &&
738 mParameters[p].maxValue == 1.0)
739 {
740 mToggles[p]->SetValue(value > 0.5);
741 }
742 else if (mParameters[p].isQuantized &&
743 mParameters[p].quantizeStep == 1.0 &&
744 !mParameters[p].valueNames.empty())
745 {
746 mChoices[p]->SetSelection(size_t(value - mParameters[p].minValue + 0.5));
747 }
748 else
749 {
750 mValues[p] = value;
751 mFields[p]->GetValidator()->TransferToWindow();
752
753 float lower = mParameters[p].minValue;
754 float upper = mParameters[p].maxValue;
755 float range = upper - lower;
756
757 if (mParameters[p].isQuantized)
758 {
759 float qs = mParameters[p].quantizeStep;
760
761 if (qs != 0.0)
762 {
763 value = (int)((value - lower) / qs + 0.5) * qs + lower;
764 }
765 }
766
767 mSliders[p]->SetValue((int)(((value - lower) / range) * 1000.0 + 0.5));
768 }
769 }
770}
771
772void VampEffect::OnCheckBox(wxCommandEvent &event)
773{
774 int p = event.GetId() - ID_Toggles;
775
776 mPlugin->setParameter(mParameters[p].identifier, mToggles[p]->GetValue());
777}
778
779void VampEffect::OnChoice(wxCommandEvent & evt)
780{
781 int p = evt.GetId();
782
783 // special value for programs
784 if (p == ID_Program)
785 {
786 Vamp::Plugin::ProgramList programs = mPlugin->getPrograms();
787 mPlugin->selectProgram(programs[evt.GetInt()]);
789 return;
790 }
791
792 mPlugin->setParameter(mParameters[p - ID_Choices].identifier, evt.GetInt());
793}
794
795void VampEffect::OnSlider(wxCommandEvent & evt)
796{
797 int p = evt.GetId() - ID_Sliders;
798
799 float lower = mParameters[p].minValue;
800 float upper = mParameters[p].maxValue;
801 float range = upper - lower;
802 float val = (evt.GetInt() / 1000.0) * range;
803
804 if (mParameters[p].isQuantized)
805 {
806 float qs = mParameters[p].quantizeStep;
807
808 if (qs != 0.0)
809 {
810 val = (int)(val / qs + 0.5) * qs;
811 }
812 }
813
814 val += lower;
815
816 mValues[p] = val;
817 mFields[p]->GetValidator()->TransferToWindow();
818
819 mPlugin->setParameter(mParameters[p].identifier, val);
820}
821
822void VampEffect::OnTextCtrl(wxCommandEvent & evt)
823{
824 int p = evt.GetId() - ID_Texts;
825
826 mFields[p]->GetValidator()->TransferFromWindow();
827
828 float lower = mParameters[p].minValue;
829 float upper = mParameters[p].maxValue;
830 float range = upper - lower;
831 float val = mValues[p];
832
833 if (mParameters[p].isQuantized)
834 {
835 float qs = mParameters[p].quantizeStep;
836
837 if (qs != 0.0)
838 {
839 val = (int)((val - lower) / qs + 0.5) * qs + lower;
840 }
841 }
842
843 mPlugin->setParameter(mParameters[p].identifier, val);
844
845 mSliders[p]->SetValue((int)(((val - lower) / range) * 1000.0 + 0.5));
846}
847
848#endif
END_EVENT_TABLE()
static const AudacityProject::AttachedObjects::RegisteredFactory key
#define str(a)
const TranslatableString name
Definition: Distortion.cpp:82
EffectType
@ EffectTypeAnalyze
wxString PluginPath
type alias for identifying a Plugin supplied by a module, each module defining its own interpretation...
Definition: Identifier.h:214
#define LAT1CTOWX(X)
Definition: Internat.h:160
#define XXO(s)
Definition: Internat.h:44
#define XO(s)
Definition: Internat.h:31
#define _(s)
Definition: Internat.h:75
size_t limitSampleBufferSize(size_t bufferSize, sampleCount limit)
Definition: SampleCount.cpp:23
TranslatableString label
Definition: TagsEditor.cpp:163
#define S(N)
Definition: ToChars.cpp:64
static Settings & settings()
Definition: TrackInfo.cpp:87
TranslatableString Verbatim(wxString str)
Require calls to the one-argument constructor to go through this distinct global function name.
std::vector< TranslatableString > TranslatableStrings
@ ID_Texts
Definition: VampEffect.cpp:51
@ ID_Choices
Definition: VampEffect.cpp:50
@ ID_Program
Definition: VampEffect.cpp:48
@ ID_Sliders
Definition: VampEffect.cpp:49
@ ID_Toggles
Definition: VampEffect.cpp:52
#define VAMPEFFECTS_FAMILY
Definition: VampEffect.h:35
void reinit(Integral count, bool initialize=false)
Definition: MemoryX.h:57
size_t size() const
How many attachment pointers are in the Site.
Definition: ClientData.h:251
CommandParameters, derived from wxFileConfig, is essentially doing the same things as the SettingsVis...
bool WriteEnum(const wxString &key, int value, const EnumValueSymbol choices[], size_t nChoices)
bool ReadEnum(const wxString &key, int *pi, const EnumValueSymbol choices[], size_t nChoices, const ObsoleteMap obsoletes[]=nullptr, size_t nObsoletes=0) const
ComponentInterfaceSymbol pairs a persistent string identifier used internally with an optional,...
const wxString Translation() const
const TrackList * inputTracks() const
Definition: EffectBase.h:102
double mProjectRate
Definition: EffectBase.h:99
bool TrackGroupProgress(int whichGroup, double frac, const TranslatableString &={}) const
Definition: Effect.cpp:700
int MessageBox(const TranslatableString &message, long style=DefaultMessageBoxStyle, const TranslatableString &titleStr={}) const
Definition: Effect.cpp:869
bool TrackProgress(int whichTrack, double frac, const TranslatableString &={}) const
Definition: Effect.cpp:691
void GetBounds(const WaveTrack &track, const WaveTrack *pRight, sampleCount *start, sampleCount *len)
Definition: Effect.cpp:709
std::shared_ptr< AddedAnalysisTrack > AddAnalysisTrack(const wxString &name=wxString())
Definition: Effect.cpp:802
int GetNumWaveGroups() const
Definition: Effect.h:188
Performs effect computation.
Abstract base class used in importing a file.
static wxString ToDisplayString(double numberToConvert, int digitsAfterDecimalPoint=-1)
Convert a number to a string, uses the user's locale's decimal separator.
Definition: Internat.cpp:162
A LabelTrack is a Track that holds labels (LabelStruct).
Definition: LabelTrack.h:89
int AddLabel(const SelectedRegion &region, const wxString &title)
Definition: LabelTrack.cpp:950
bool GetFloats(float *buffer, sampleCount start, size_t len, fillFormat fill=fillZero, bool mayThrow=true, sampleCount *pNumWithinClips=nullptr) const
Retrieve samples from a track in floating-point format, regardless of the storage format.
Definition: SampleTrack.h:65
Defines a selected portion of a project.
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
Definition: ShuttleGui.h:628
static auto Channels(TrackType *pTrack) -> TrackIterRange< TrackType >
Definition: Track.h:1533
Holds a msgid for the translation catalog; may also bind format arguments.
ArrayOf< wxCheckBox * > mToggles
Definition: VampEffect.h:109
void OnCheckBox(wxCommandEvent &evt)
Definition: VampEffect.cpp:772
Floats mValues
Definition: VampEffect.h:104
bool IsDefault() const override
Whether the effect sorts "above the line" in the menus.
Definition: VampEffect.cpp:135
PluginPath GetPath() const override
Definition: VampEffect.cpp:90
bool TransferDataToWindow(const EffectSettings &settings) override
Update controls for the settings.
Definition: VampEffect.cpp:691
ComponentInterfaceSymbol GetSymbol() const override
Definition: VampEffect.cpp:95
EffectFamilySymbol GetFamily() const override
Report identifier and user-visible name of the effect protocol.
Definition: VampEffect.cpp:125
bool IsInteractive() const override
Whether the effect needs a dialog for entry of settings.
Definition: VampEffect.cpp:130
void OnTextCtrl(wxCommandEvent &evt)
Definition: VampEffect.cpp:822
double mRate
Definition: VampEffect.h:97
ArrayOf< wxSlider * > mSliders
Definition: VampEffect.h:106
void UpdateFromPlugin()
Definition: VampEffect.cpp:729
PluginPath mPath
Definition: VampEffect.h:91
EffectType GetType() const override
Type determines how it behaves.
Definition: VampEffect.cpp:120
VendorSymbol GetVendor() const override
Definition: VampEffect.cpp:100
Vamp::Plugin::ParameterList mParameters
Definition: VampEffect.h:102
ArrayOf< wxChoice * > mChoices
Definition: VampEffect.h:110
ArrayOf< wxStaticText * > mLabels
Definition: VampEffect.h:108
int mOutput
Definition: VampEffect.h:92
wxChoice * mProgram
Definition: VampEffect.h:111
wxString mName
Definition: VampEffect.h:96
std::unique_ptr< Vamp::Plugin > mPlugin
Definition: VampEffect.h:90
TranslatableString GetDescription() const override
Definition: VampEffect.cpp:110
bool Process(EffectInstance &instance, EffectSettings &settings) override
Actually do the effect here.
Definition: VampEffect.cpp:343
ArrayOf< wxTextCtrl * > mFields
Definition: VampEffect.h:107
bool mHasParameters
Definition: VampEffect.h:93
virtual ~VampEffect()
Definition: VampEffect.cpp:82
bool Init() override
Call once to set up state for whole list of tracks to be processed.
Definition: VampEffect.cpp:298
bool SaveSettings(const EffectSettings &settings, CommandParameters &parms) const override
Store settings as keys and values.
Definition: VampEffect.cpp:145
void OnSlider(wxCommandEvent &evt)
Definition: VampEffect.cpp:795
bool LoadSettings(const CommandParameters &parms, EffectSettings &settings) const override
Restore settings from keys and values.
Definition: VampEffect.cpp:192
unsigned GetAudioInCount() const override
How many input buffers to allocate at once.
Definition: VampEffect.cpp:140
Vamp::HostExt::PluginLoader::PluginKey mKey
Definition: VampEffect.h:95
std::unique_ptr< EffectUIValidator > PopulateOrExchange(ShuttleGui &S, EffectInstance &instance, EffectSettingsAccess &access) override
Add controls to effect panel; always succeeds.
Definition: VampEffect.cpp:529
wxString GetVersion() const override
Definition: VampEffect.cpp:105
void OnChoice(wxCommandEvent &evt)
Definition: VampEffect.cpp:779
void AddFeatures(LabelTrack *track, Vamp::Plugin::FeatureSet &features)
Definition: VampEffect.cpp:699
A Track that contains audio waveform data.
Definition: WaveTrack.h:57
Positions or offsets within audio files need a wide type.
Definition: SampleCount.h:18
auto begin(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
Definition: PackedArray.h:150
STL namespace.
Externalized state of a plug-in.