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