Audacity 3.2.0
VST3Instance.cpp
Go to the documentation of this file.
1#include "VST3Instance.h"
2
3#include <public.sdk/source/vst/utility/uid.h>
4
5#include "AudacityException.h"
6#include "VST3Wrapper.h"
7#include "ConfigInterface.h"
8#include "VST3Utils.h"
9
10namespace
11{
12 unsigned CountChannels(Steinberg::Vst::IComponent* component,
13 const Steinberg::Vst::MediaTypes mediaType,
14 const Steinberg::Vst::BusDirection busDirection,
15 const Steinberg::Vst::BusType busType)
16 {
17 using namespace Steinberg;
18
19 unsigned channelsCount{0};
20
21 const auto busCount = component->getBusCount(mediaType, busDirection);
22 for(auto i = 0; i < busCount; ++i)
23 {
24 Vst::BusInfo busInfo;
25 if(component->getBusInfo(mediaType, busDirection, i, busInfo) == kResultOk)
26 {
27 if(busInfo.busType == busType)
28 channelsCount += busInfo.channelCount;
29 }
30 }
31 return channelsCount;
32 }
33}
34
35VST3Instance::VST3Instance(const PerTrackEffect& effect, VST3::Hosting::Module& module, const VST3::Hosting::ClassInfo& effectClassInfo)
36 : Instance(effect)
37{
39 mWrapper = std::make_unique<VST3Wrapper>(module, effectClassInfo);
40 mWrapper->InitializeComponents();
41}
42
44
46{
47 return Instance::GetTailSize();
48}
49
51 EffectOutputs *, unsigned, float sampleRate)
52{
53 if (!mRecruited) {
54 // Assign self to the first processor
55 mRecruited = true;
56 return true;
57 }
58 // Assign another instance with independent state to other processors
59 auto &effect = static_cast<const PerTrackEffect&>(mProcessor);
60 auto uProcessor =
61 std::make_unique<VST3Instance>(effect, mWrapper->GetModule(), mWrapper->GetEffectClassInfo());
62 if (!uProcessor->RealtimeInitialize(settings, sampleRate))
63 return false;
64 mProcessors.push_back(move(uProcessor));
65 return true;
66}
67
69{
70return GuardedCall<bool>([&]{
71 mRecruited = false;
72 mWrapper->Finalize(&settings);
73 for (auto &pProcessor : mProcessors)
74 pProcessor->mWrapper->Finalize(nullptr);
75 mProcessors.clear();
76 return true;
77});
78}
79
81{
82 if(mWrapper->Initialize(settings, sampleRate, Steinberg::Vst::kRealtime, mProcessingBlockSize))
83 {
84 mInitialDelay = mWrapper->GetLatencySamples();
85 return true;
86 }
87 return false;
88}
89
90size_t VST3Instance::RealtimeProcess(size_t group, EffectSettings& settings, const float* const* inBuf,
91 float* const* outBuf, size_t numSamples)
92{
93 if (!mRecruited)
94 // unexpected!
95 return 0;
96 if (group == 0)
97 return mWrapper->Process(inBuf, outBuf, numSamples);
98 else if (--group < mProcessors.size())
99 return mProcessors[group]->mWrapper->Process(inBuf, outBuf, numSamples);
100 return 0;
101}
102
104{
105 return true;
106}
107
109{
110 auto &settings = package.settings;
111 mWrapper->ProcessBlockStart(settings);
112 for (auto &pProcessor : mProcessors)
113 pProcessor->mWrapper->ProcessBlockStart(settings);
114 return true;
115}
116
118{
119 mWrapper->ResumeProcessing();
120 for (auto &pProcessor : mProcessors)
121 pProcessor->mWrapper->ResumeProcessing();
122 return true;
123}
124
126{
127 mWrapper->SuspendProcessing();
128 for (auto &pProcessor : mProcessors)
129 pProcessor->mWrapper->SuspendProcessing();
130 return true;
131}
132
134 const -> SampleCount
135{
136 if(mUseLatency)
137 return mInitialDelay.as_long_long();
138 return 0;
139}
140
142{
143 return GuardedCall<bool>([&]
144 {
145 mWrapper->Finalize(nullptr);
146 return true;
147 });
148}
149
151{
152 if(mWrapper->Initialize(settings, sampleRate, Steinberg::Vst::kOffline, mProcessingBlockSize))
153 {
154 mInitialDelay = mWrapper->GetLatencySamples();
155 return true;
156 }
157 return false;;
158}
159
161{
163}
164
166{
168 static_cast<Steinberg::int32>(std::min(maxBlockSize, mUserBlockSize));
170}
171
172size_t VST3Instance::ProcessBlock(EffectSettings& settings, const float* const* inBlock, float* const* outBlock,
173 size_t blockLen)
174{
175 return mWrapper->Process(inBlock, outBlock, blockLen);
176}
177
179{
180 return *mWrapper;
181}
182
184{
185 //setupProcessing should be called first
186 return CountChannels(
187 mWrapper->mEffectComponent,
188 Steinberg::Vst::kAudio,
189 Steinberg::Vst::kInput,
190 Steinberg::Vst::kMain
191 );
192}
193
195{
196 //setupProcessing should be called first
197 return CountChannels(
198 mWrapper->mEffectComponent,
199 Steinberg::Vst::kAudio,
200 Steinberg::Vst::kOutput,
201 Steinberg::Vst::kMain
202 );
203}
204
206{
207 // Reinitialize configuration settings
208 int userBlockSize;
210 wxT("BufferSize"), userBlockSize, 8192);
211 mUserBlockSize = std::max( 1, userBlockSize );
213 wxT("UseLatency"), mUseLatency, true);
214
216}
wxT("CloseDown"))
Declare abstract class AudacityException, some often-used subclasses, and GuardedCall.
int min(int a, int b)
ChannelName
static Settings & settings()
Definition: TrackInfo.cpp:69
uint64_t SampleCount
Hold values to send to effect output meters.
const PerTrackEffect & mProcessor
Base class for many of the effects in Audacity.
size_t mProcessingBlockSize
Definition: VST3Instance.h:34
~VST3Instance() override
bool RealtimeProcessEnd(EffectSettings &settings) noexcept override
settings can be updated to let a dialog change appearance at idle
SampleCount GetLatency(const EffectSettings &settings, double sampleRate) const override
void ReloadUserOptions()
std::vector< std::unique_ptr< VST3Instance > > mProcessors
Definition: VST3Instance.h:39
bool RealtimeFinalize(EffectSettings &settings) noexcept override
size_t GetTailSize() const override
size_t SetBlockSize(size_t maxBlockSize) override
bool ProcessFinalize() noexcept override
size_t ProcessBlock(EffectSettings &settings, const float *const *inBlock, float *const *outBlock, size_t blockLen) override
Called for destructive effect computation.
VST3Instance(const PerTrackEffect &effect, VST3::Hosting::Module &module, const VST3::Hosting::ClassInfo &effectClassInfo)
unsigned GetAudioInCount() const override
How many input buffers to allocate at once.
bool mUseLatency
Definition: VST3Instance.h:35
size_t mUserBlockSize
Definition: VST3Instance.h:33
bool RealtimeInitialize(EffectSettings &settings, double sampleRate) override
bool RealtimeSuspend() override
sampleCount mInitialDelay
Definition: VST3Instance.h:36
std::unique_ptr< VST3Wrapper > mWrapper
Definition: VST3Instance.h:31
size_t RealtimeProcess(size_t group, EffectSettings &settings, const float *const *inBuf, float *const *outBuf, size_t numSamples) override
VST3Wrapper & GetWrapper()
bool ProcessInitialize(EffectSettings &settings, double sampleRate, ChannelNames chanMap) override
bool RealtimeAddProcessor(EffectSettings &settings, EffectOutputs *pOutputs, unsigned numChannels, float sampleRate) override
size_t GetBlockSize() const override
unsigned GetAudioOutCount() const override
How many output buffers to allocate at once.
bool RealtimeProcessStart(MessagePackage &package) override
settings are possibly changed, since last call, by an asynchronous dialog
bool RealtimeResume() override
bool GetConfig(const EffectDefinitionInterface &ident, ConfigurationType type, const RegistryPath &group, const RegistryPath &key, Value &var, const Value &defval)
unsigned CountChannels(Steinberg::Vst::IComponent *component, const Steinberg::Vst::MediaTypes mediaType, const Steinberg::Vst::BusDirection busDirection, const Steinberg::Vst::BusType busType)
Externalized state of a plug-in.