19#include <vamp-hostsdk/Plugin.h>
20#include <vamp-hostsdk/PluginChannelAdapter.h>
21#include <vamp-hostsdk/PluginInputDomainAdapter.h>
25#include <wx/checkbox.h>
27#include <wx/combobox.h>
30#include <wx/statbox.h>
31#include <wx/stattext.h>
32#include <wx/textctrl.h>
33#include <wx/tokenzr.h>
35#include <wx/scrolwin.h>
36#include <wx/version.h>
39#include "../../ShuttleGui.h"
40#include "../../widgets/valnum.h"
41#include "../../widgets/AudacityMessageBox.h"
43#include "../../LabelTrack.h"
44#include "../../WaveTrack.h"
72: mPlugin(
std::move(plugin)),
75 mHasParameters(hasParameters),
78 mKey = mPath.BeforeLast(wxT(
'/')).ToUTF8();
79 mName = mPath.AfterLast(wxT(
'/'));
102 return { wxString::FromUTF8(
mPlugin->getMaker().c_str()) };
107 return wxString::Format(wxT(
"%d"),
mPlugin->getPluginVersion());
113 wxString::FromUTF8(
mPlugin->getCopyright().c_str()) );
142 return mPlugin->getMaxChannelCount();
148 for (
size_t p = 0, paramCount =
mParameters.size(); p < paramCount; p++)
150 wxString
key = wxString::FromUTF8(
mParameters[p].identifier.c_str());
160 bool val = value > 0.5;
162 parms.Write(
key, val);
168 std::vector<EnumValueSymbol> choices;
171 for (
size_t i = 0, choiceCount =
mParameters[p].valueNames.size(); i < choiceCount; i++)
173 wxString choice = wxString::FromUTF8(
mParameters[p].valueNames[i].c_str());
174 if (
size_t(value -
mParameters[p].minValue + 0.5) == i)
178 choices.push_back(choice);
181 parms.
WriteEnum(
key, val, choices.data(), choices.size());
185 parms.Write(
key, value);
196 for (
size_t p = 0, paramCount =
mParameters.size(); p < paramCount; p++)
198 wxString
key = wxString::FromUTF8(
mParameters[p].identifier.c_str());
210 good = parms.Read(
key, &val);
216 std::vector<EnumValueSymbol> choices;
219 for (
size_t i = 0, choiceCount =
mParameters[p].valueNames.size(); i < choiceCount; i++)
221 wxString choice = wxString::FromUTF8(
mParameters[p].valueNames[i].c_str());
222 choices.push_back(choice);
225 good = parms.
ReadEnum(
key, &val, choices.data(), choices.size()) && val != wxNOT_FOUND;
231 good = parms.Read(
key, &val) && val >= lower && val <= upper;
241 for (
size_t p = 0, paramCount =
mParameters.size(); p < paramCount; p++)
243 wxString
key = wxString::FromUTF8(
mParameters[p].identifier.c_str());
254 parms.Read(
key, &val);
262 std::vector<EnumValueSymbol> choices;
265 for (
size_t i = 0, choiceCount =
mParameters[p].valueNames.size(); i < choiceCount; i++)
267 wxString choice = wxString::FromUTF8(
mParameters[p].valueNames[i].c_str());
268 choices.push_back(choice);
271 parms.
ReadEnum(
key, &val, choices.data(), choices.size());
279 parms.Read(
key, &val);
287 val = (int)((val - lower) / qs + 0.5) * qs + lower;
306 for (
auto leader :
inputTracks()->Leaders<const WaveTrack>()) {
308 auto rate = (*channelGroup.first++) ->
GetRate();
309 for(
auto channel : channelGroup) {
310 if (rate != channel->GetRate())
317"Sorry, Vamp Plug-ins cannot be run on stereo tracks where the individual channels of the track do not match.") );
332 Vamp::HostExt::PluginLoader *loader = Vamp::HostExt::PluginLoader::getInstance();
333 mPlugin.reset(loader->loadPlugin(
mKey,
mRate, Vamp::HostExt::PluginLoader::ADAPT_ALL));
352 bool multiple =
false;
353 unsigned prevTrackChannels = 0;
364 std::vector<std::shared_ptr<Effect::AddedAnalysisTrack>> addedTracks;
366 for (
auto leader :
inputTracks()->Leaders<const WaveTrack>())
369 auto left = *channelGroup.first++;
371 unsigned channels = 1;
375 channelGroup.
size() ? *channelGroup.first++ :
nullptr;
385 size_t step =
mPlugin->getPreferredStepSize();
386 size_t block =
mPlugin->getPreferredBlockSize();
388 bool initialiseRequired =
true;
407 if (prevTrackChannels > 0)
413 if (prevTrackChannels == channels)
416 initialiseRequired =
false;
425 if (initialiseRequired)
427 if (!
mPlugin->initialise(channels, step, block))
430 XO(
"Sorry, Vamp Plug-in failed to initialize.") );
438 ? wxString::Format(
_(
"%s: %s"), left->GetName(), effectName )
441 LabelTrack *ltrack = addedTracks.back()->get();
445 auto originalLen = len;
455 left->GetFloats(data[0].get(), pos, request);
460 right->
GetFloats(data[1].get(), pos, request);
465 for (
unsigned int c = 0; c < channels; ++c)
467 for (
decltype(block) i = request; i < block; ++i)
476 Vamp::RealTime timestamp = Vamp::RealTime::frame2RealTime(
477 long( pos.as_long_long() ),
481 Vamp::Plugin::FeatureSet features =
mPlugin->process(
482 reinterpret_cast< float**
>( data.get() ), timestamp);
499 (pos - start).as_double() /
500 originalLen.as_double() ))
508 (pos - start).as_double() /
509 originalLen.as_double() ))
516 Vamp::Plugin::FeatureSet features =
mPlugin->getRemainingFeatures();
519 prevTrackChannels = channels;
523 for (
auto &addedTrack : addedTracks)
524 addedTrack->Commit();
532 Vamp::Plugin::ProgramList programs =
mPlugin->getPrograms();
545 wxScrolledWindow *scroller =
S.Style(wxVSCROLL | wxTAB_TRAVERSAL)
548 S.StartStatic(
XO(
"Plugin Settings"));
550 S.StartMultiColumn(5, wxEXPAND);
554 if (!programs.empty())
556 S.AddPrompt(
XXO(
"Program"));
560 .MinSize( { -1, -1 } )
561 .Position(wxEXPAND | wxALIGN_CENTER_VERTICAL | wxALL)
565 for (
const auto &program : programs)
567 Verbatim(wxString::FromUTF8(program.c_str())));
578 for (
size_t p = 0; p < count; p++)
580 wxString tip = wxString::FromUTF8(
mParameters[p].description.c_str());
581 wxString unit = wxString::FromUTF8(
mParameters[p].unit.c_str());
594 labelText += wxT(
" (") + unit + wxT(
")");
608 .Position(wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL)
624 for (
size_t i = 0, cnt =
mParameters[p].valueNames.size(); i < cnt; i++)
626 wxString choice = wxString::FromUTF8(
mParameters[p].valueNames[i].c_str());
627 if (
size_t(value -
mParameters[p].minValue + 0.5) == i)
631 choices.push_back(
Verbatim( choice ) );
637 .Position(wxEXPAND | wxALIGN_CENTER_VERTICAL | wxALL)
638 .MinSize( { -1, -1 } )
639 .AddChoice( {}, choices, selected );
654 .Position(wxALIGN_CENTER_VERTICAL | wxALL)
655 .Validator<FloatingPointValidator<float>>(
658 ? NumValidatorStyle::THREE_TRAILING_ZEROES
660 ? NumValidatorStyle::TWO_TRAILING_ZEROES
661 : NumValidatorStyle::ONE_TRAILING_ZERO),
663 .AddTextBox( {}, wxT(
""), 12);
671 .Style(wxSL_HORIZONTAL)
672 .MinSize( { 150, -1 } )
673 .AddSlider( {}, 0, 1000, 0);
686 scroller->SetScrollRate(0, 20);
700 Vamp::Plugin::FeatureSet &features)
702 for (Vamp::Plugin::FeatureList::iterator fli = features[
mOutput].
begin();
703 fli != features[
mOutput].end(); ++fli)
705 Vamp::RealTime ftime0 = fli->timestamp;
706 double ltime0 = ftime0.sec + (double(ftime0.nsec) / 1000000000.0);
708 Vamp::RealTime ftime1 = ftime0;
709 if (fli->hasDuration) ftime1 = ftime0 + fli->duration;
710 double ltime1 = ftime1.sec + (double(ftime1.nsec) / 1000000000.0);
713 if (
label == wxString())
715 if (fli->values.empty())
721 label = wxString::Format(
LAT1CTOWX(
"%.3f"), *fli->values.begin());
731 for (
size_t p = 0, cnt =
mParameters.size(); p < cnt; p++)
751 mFields[p]->GetValidator()->TransferToWindow();
755 float range = upper - lower;
763 value = (int)((value - lower) / qs + 0.5) * qs + lower;
767 mSliders[p]->SetValue((
int)(((value - lower) / range) * 1000.0 + 0.5));
786 Vamp::Plugin::ProgramList programs =
mPlugin->getPrograms();
787 mPlugin->selectProgram(programs[evt.GetInt()]);
801 float range = upper - lower;
802 float val = (evt.GetInt() / 1000.0) * range;
810 val = (int)(val / qs + 0.5) * qs;
817 mFields[p]->GetValidator()->TransferToWindow();
826 mFields[p]->GetValidator()->TransferFromWindow();
830 float range = upper - lower;
839 val = (int)((val - lower) / qs + 0.5) * qs + lower;
845 mSliders[p]->SetValue((
int)(((val - lower) / range) * 1000.0 + 0.5));
static const AudacityProject::AttachedObjects::RegisteredFactory key
const TranslatableString name
wxString PluginPath
type alias for identifying a Plugin supplied by a module, each module defining its own interpretation...
size_t limitSampleBufferSize(size_t bufferSize, sampleCount limit)
static Settings & settings()
TranslatableString Verbatim(wxString str)
Require calls to the one-argument constructor to go through this distinct global function name.
std::vector< TranslatableString > TranslatableStrings
#define VAMPEFFECTS_FAMILY
void reinit(Integral count, bool initialize=false)
size_t size() const
How many attachment pointers are in the Site.
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
bool TrackGroupProgress(int whichGroup, double frac, const TranslatableString &={}) const
int MessageBox(const TranslatableString &message, long style=DefaultMessageBoxStyle, const TranslatableString &titleStr={}) const
bool TrackProgress(int whichTrack, double frac, const TranslatableString &={}) const
void GetBounds(const WaveTrack &track, const WaveTrack *pRight, sampleCount *start, sampleCount *len)
std::shared_ptr< AddedAnalysisTrack > AddAnalysisTrack(const wxString &name=wxString())
int GetNumWaveGroups() const
Performs effect computation.
static wxString ToDisplayString(double numberToConvert, int digitsAfterDecimalPoint=-1)
Convert a number to a string, uses the user's locale's decimal separator.
A LabelTrack is a Track that holds labels (LabelStruct).
int AddLabel(const SelectedRegion ®ion, const wxString &title)
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.
Defines a selected portion of a project.
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
static auto Channels(TrackType *pTrack) -> TrackIterRange< TrackType >
Holds a msgid for the translation catalog; may also bind format arguments.
ArrayOf< wxCheckBox * > mToggles
void OnCheckBox(wxCommandEvent &evt)
bool IsDefault() const override
Whether the effect sorts "above the line" in the menus.
PluginPath GetPath() const override
bool TransferDataToWindow(const EffectSettings &settings) override
Update controls for the settings.
ComponentInterfaceSymbol GetSymbol() const override
EffectFamilySymbol GetFamily() const override
Report identifier and user-visible name of the effect protocol.
bool IsInteractive() const override
Whether the effect needs a dialog for entry of settings.
void OnTextCtrl(wxCommandEvent &evt)
ArrayOf< wxSlider * > mSliders
EffectType GetType() const override
Type determines how it behaves.
VendorSymbol GetVendor() const override
Vamp::Plugin::ParameterList mParameters
ArrayOf< wxChoice * > mChoices
ArrayOf< wxStaticText * > mLabels
std::unique_ptr< Vamp::Plugin > mPlugin
TranslatableString GetDescription() const override
bool Process(EffectInstance &instance, EffectSettings &settings) override
Actually do the effect here.
ArrayOf< wxTextCtrl * > mFields
bool Init() override
Call once to set up state for whole list of tracks to be processed.
bool SaveSettings(const EffectSettings &settings, CommandParameters &parms) const override
Store settings as keys and values.
void OnSlider(wxCommandEvent &evt)
bool LoadSettings(const CommandParameters &parms, EffectSettings &settings) const override
Restore settings from keys and values.
unsigned GetAudioInCount() const override
How many input buffers to allocate at once.
Vamp::HostExt::PluginLoader::PluginKey mKey
std::unique_ptr< EffectUIValidator > PopulateOrExchange(ShuttleGui &S, EffectInstance &instance, EffectSettingsAccess &access) override
Add controls to effect panel; always succeeds.
wxString GetVersion() const override
void OnChoice(wxCommandEvent &evt)
void AddFeatures(LabelTrack *track, Vamp::Plugin::FeatureSet &features)
A Track that contains audio waveform data.
Positions or offsets within audio files need a wide type.
auto begin(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
Externalized state of a plug-in.