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