55 * MuseScore
66 * Music Composition & Notation
77 *
8- * Copyright (C) 2021 MuseScore Limited and others
8+ * Copyright (C) 2025 MuseScore Limited and others
99 *
1010 * This program is free software: you can redistribute it and/or modify
1111 * it under the terms of the GNU General Public License version 3 as
@@ -46,15 +46,14 @@ VstAudioClient::~VstAudioClient()
4646 m_pluginComponent->terminate ();
4747}
4848
49- void VstAudioClient::init (AudioPluginType type, IVstPluginInstancePtr instance, audioch_t audioChannelsCount )
49+ void VstAudioClient::init (AudioPluginType type, IVstPluginInstancePtr instance)
5050{
5151 IF_ASSERT_FAILED (instance && type != AudioPluginType::Undefined) {
5252 return ;
5353 }
5454
5555 m_type = type;
5656 m_pluginPtr = std::move (instance);
57- m_audioChannelsCount = audioChannelsCount;
5857}
5958
6059void VstAudioClient::loadSupportedParams ()
@@ -90,6 +89,36 @@ void VstAudioClient::setIsActive(const bool isActive)
9089 }
9190}
9291
92+ void VstAudioClient::setOutputSpec (const audio::OutputSpec& spec)
93+ {
94+ if (m_outputSpec == spec) {
95+ return ;
96+ }
97+
98+ m_processData.numSamples = static_cast <Steinberg::int32>(spec.samplesPerChannel );
99+ m_outputSpec = spec;
100+ m_needUnprepareProcessData = true ;
101+
102+ updateProcessSetup ();
103+ }
104+
105+ void VstAudioClient::setProcessMode (VstProcessMode mode)
106+ {
107+ if (m_processMode == mode) {
108+ return ;
109+ }
110+
111+ m_processMode = mode;
112+ m_needUnprepareProcessData = true ;
113+
114+ updateProcessSetup ();
115+ }
116+
117+ void VstAudioClient::setVolumeGain (const muse::audio::gain_t newVolumeGain)
118+ {
119+ m_volumeGain = newVolumeGain;
120+ }
121+
93122bool VstAudioClient::handleEvent (const VstEvent& event)
94123{
95124 ensureActivity ();
@@ -119,58 +148,6 @@ bool VstAudioClient::handleParamChange(const ParamChangeEvent& param)
119148 return true ;
120149}
121150
122- void VstAudioClient::setVolumeGain (const muse::audio::gain_t newVolumeGain)
123- {
124- m_volumeGain = newVolumeGain;
125- }
126-
127- muse::audio::samples_t VstAudioClient::process (float * output, muse::audio::samples_t samplesPerChannel,
128- muse::audio::msecs_t playbackPosition)
129- {
130- IAudioProcessorPtr processor = pluginProcessor ();
131- if (!processor || !output) {
132- return 0 ;
133- }
134-
135- if (!m_isActive) {
136- return 0 ;
137- }
138-
139- // ! NOTE: From the VST3 documentation:
140- // !
141- // ! Note that the ProcessData->numSamples
142- // ! which indicates how many samples are used in a process call can change from call to call,
143- // ! but never bigger than the maxSamplesPerBlock
144- m_processData.numSamples = samplesPerChannel;
145-
146- m_processContext.projectTimeSamples = (playbackPosition / 1000000 .f ) * m_samplesInfo.sampleRate ;
147-
148- if (samplesPerChannel > m_samplesInfo.maxSamplesPerBlock ) {
149- setMaxSamplesPerBlock (samplesPerChannel);
150- }
151-
152- if (m_type == AudioPluginType::Fx) {
153- extractInputSamples (samplesPerChannel, output);
154- }
155-
156- if (processor->process (m_processData) != Steinberg::kResultOk ) {
157- return 0 ;
158- }
159-
160- if (m_type == AudioPluginType::Instrument) {
161- m_eventList.clear ();
162- m_paramChanges.clearQueue ();
163-
164- if (!fillOutputBufferInstrument (samplesPerChannel, output)) {
165- return 0 ;
166- }
167- } else if (!fillOutputBufferFx (samplesPerChannel, output)) {
168- return 0 ;
169- }
170-
171- return samplesPerChannel;
172- }
173-
174151void VstAudioClient::flushSound ()
175152{
176153 if (m_playingNotes.empty () && m_playingParams.empty ()) {
@@ -217,42 +194,53 @@ void VstAudioClient::flushSound()
217194 m_playingParams.clear ();
218195}
219196
220- samples_t VstAudioClient::maxSamplesPerBlock () const
197+ muse::audio::samples_t VstAudioClient::process (float * output, muse::audio::samples_t samplesPerChannel,
198+ muse::audio::msecs_t playbackPosition)
221199{
222- return m_samplesInfo.maxSamplesPerBlock ;
223- }
200+ IAudioProcessorPtr processor = pluginProcessor ();
201+ if (!processor || !output) {
202+ return 0 ;
203+ }
224204
225- void VstAudioClient::setMaxSamplesPerBlock (samples_t samples)
226- {
227- if (m_samplesInfo.maxSamplesPerBlock == samples) {
228- return ;
205+ if (!m_isActive) {
206+ return 0 ;
229207 }
230208
231- m_processData.numSamples = static_cast <Steinberg::int32>(samples);
232- m_samplesInfo.maxSamplesPerBlock = samples;
233- m_needUnprepareProcessData = true ;
209+ // ! NOTE: From the VST3 documentation:
210+ // !
211+ // ! Note that the ProcessData->numSamples
212+ // ! which indicates how many samples are used in a process call can change from call to call,
213+ // ! but never bigger than the maxSamplesPerBlock
214+ m_processData.numSamples = samplesPerChannel;
234215
235- updateProcessSetup ();
236- }
216+ m_processContext.projectTimeSamples = (playbackPosition / 1000000 .f ) * m_outputSpec.sampleRate ;
237217
238- void VstAudioClient::setSampleRate ( unsigned int sampleRate)
239- {
240- if (m_samplesInfo. sampleRate == sampleRate) {
241- return ;
218+ if (samplesPerChannel > m_outputSpec. samplesPerChannel ) {
219+ OutputSpec newSpec = m_outputSpec;
220+ newSpec. samplesPerChannel = samplesPerChannel;
221+ setOutputSpec (newSpec) ;
242222 }
243223
244- m_samplesInfo. sampleRate = sampleRate;
245- updateProcessSetup ( );
246- }
224+ if (m_type == AudioPluginType::Fx) {
225+ extractInputSamples (samplesPerChannel, output );
226+ }
247227
248- void VstAudioClient::setProcessMode (VstProcessMode mode)
249- {
250- if (m_processMode == mode) {
251- return ;
228+ if (processor->process (m_processData) != Steinberg::kResultOk ) {
229+ return 0 ;
252230 }
253231
254- m_processMode = mode;
255- updateProcessSetup ();
232+ if (m_type == AudioPluginType::Instrument) {
233+ m_eventList.clear ();
234+ m_paramChanges.clearQueue ();
235+
236+ if (!fillOutputBufferInstrument (samplesPerChannel, output)) {
237+ return 0 ;
238+ }
239+ } else if (!fillOutputBufferFx (samplesPerChannel, output)) {
240+ return 0 ;
241+ }
242+
243+ return samplesPerChannel;
256244}
257245
258246ParamsMapping VstAudioClient::paramsMapping (const std::set<Steinberg::Vst::CtrlNumber>& controllers) const
@@ -308,8 +296,7 @@ void VstAudioClient::setUpProcessData()
308296 return ;
309297 }
310298
311- m_processContext.sampleRate = m_samplesInfo.sampleRate ;
312-
299+ m_processContext.sampleRate = m_outputSpec.sampleRate ;
313300 m_processData.inputEvents = &m_eventList;
314301 m_processData.inputParameterChanges = &m_paramChanges;
315302 m_processData.processContext = &m_processContext;
@@ -320,7 +307,7 @@ void VstAudioClient::setUpProcessData()
320307 }
321308
322309 if (!m_processData.outputs || !m_processData.inputs ) {
323- m_processData.prepare (*component, m_samplesInfo. maxSamplesPerBlock , Steinberg::Vst::kSample32 );
310+ m_processData.prepare (*component, m_outputSpec. samplesPerChannel , Steinberg::Vst::kSample32 );
324311 }
325312
326313 if (!m_activeOutputBusses.empty () && !m_activeInputBusses.empty ()) {
@@ -376,7 +363,7 @@ void VstAudioClient::setUpProcessData()
376363
377364void VstAudioClient::updateProcessSetup ()
378365{
379- if (!m_samplesInfo .isValid ()) {
366+ if (!m_outputSpec .isValid ()) {
380367 return ;
381368 }
382369
@@ -390,8 +377,8 @@ void VstAudioClient::updateProcessSetup()
390377 VstProcessSetup setup;
391378 setup.processMode = m_processMode;
392379 setup.symbolicSampleSize = Steinberg::Vst::kSample32 ;
393- setup.maxSamplesPerBlock = m_samplesInfo. maxSamplesPerBlock ;
394- setup.sampleRate = m_samplesInfo .sampleRate ;
380+ setup.maxSamplesPerBlock = m_outputSpec. samplesPerChannel ;
381+ setup.sampleRate = m_outputSpec .sampleRate ;
395382
396383 if (processor->setupProcessing (setup) != Steinberg::kResultOk ) {
397384 return ;
@@ -412,7 +399,7 @@ void VstAudioClient::extractInputSamples(samples_t sampleCount, const float* sou
412399 Steinberg::Vst::AudioBusBuffers& bus = m_processData.inputs [0 ];
413400
414401 for (samples_t sampleIndex = 0 ; sampleIndex < sampleCount; ++sampleIndex) {
415- size_t offset = sampleIndex * m_audioChannelsCount ;
402+ size_t offset = sampleIndex * m_outputSpec. audioChannelCount ;
416403
417404 for (audioch_t audioChannelIndex = 0 ; audioChannelIndex < bus.numChannels ; ++audioChannelIndex) {
418405 bus.channelBuffers32 [audioChannelIndex][sampleIndex] = sourceBuffer[offset + audioChannelIndex];
@@ -432,7 +419,7 @@ bool VstAudioClient::fillOutputBufferInstrument(samples_t sampleCount, float* ou
432419 Steinberg::Vst::AudioBusBuffers bus = m_processData.outputs [busIndex];
433420
434421 for (samples_t sampleIndex = 0 ; sampleIndex < sampleCount; ++sampleIndex) {
435- size_t offset = sampleIndex * m_audioChannelsCount ;
422+ size_t offset = sampleIndex * m_outputSpec. audioChannelCount ;
436423
437424 for (audioch_t audioChannelIndex = 0 ; audioChannelIndex < bus.numChannels ; ++audioChannelIndex) {
438425 float sample = bus.channelBuffers32 [audioChannelIndex][sampleIndex];
@@ -460,7 +447,7 @@ bool VstAudioClient::fillOutputBufferFx(samples_t sampleCount, float* output)
460447 Steinberg::Vst::AudioBusBuffers bus = m_processData.outputs [busIndex];
461448
462449 for (samples_t sampleIndex = 0 ; sampleIndex < sampleCount; ++sampleIndex) {
463- size_t offset = sampleIndex * m_audioChannelsCount ;
450+ size_t offset = sampleIndex * m_outputSpec. audioChannelCount ;
464451
465452 for (audioch_t audioChannelIndex = 0 ; audioChannelIndex < bus.numChannels ; ++audioChannelIndex) {
466453 float sample = bus.channelBuffers32 [audioChannelIndex][sampleIndex];
0 commit comments