Skip to content

Commit

Permalink
VST: added allNotesOff() that doesn't disable activity to prevet stut…
Browse files Browse the repository at this point in the history
…tering
  • Loading branch information
RomanPudashkin committed Jul 17, 2024
1 parent 3cc3286 commit fcf42f3
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 23 deletions.
7 changes: 5 additions & 2 deletions src/framework/vst/internal/synth/vstsynthesiser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ void VstSynthesiser::init()
auto onPluginLoaded = [this, blockSize]() {
m_pluginPtr->updatePluginConfig(m_params.configuration);
m_vstAudioClient->setMaxSamplesPerBlock(blockSize);
m_vstAudioClient->loadSupportedParams();
m_sequencer.init(m_vstAudioClient->paramsMapping(SUPPORTED_CONTROLLERS), m_useDynamicEvents);
};

Expand Down Expand Up @@ -123,13 +124,15 @@ std::string VstSynthesiser::name() const
void VstSynthesiser::revokePlayingNotes()
{
if (m_vstAudioClient) {
m_vstAudioClient->flush();
m_vstAudioClient->allNotesOff();
}
}

void VstSynthesiser::flushSound()
{
revokePlayingNotes();
if (m_vstAudioClient) {
m_vstAudioClient->flush();
}
}

void VstSynthesiser::setupSound(const mpe::PlaybackSetupData& setupData)
Expand Down
99 changes: 81 additions & 18 deletions src/framework/vst/internal/vstaudioclient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,13 @@ using namespace muse::vst;
using namespace muse::mpe;
using namespace muse::audio;

static size_t noteEventKey(int pitch, int channel)
{
std::size_t h1 = std::hash<int> {}(pitch);
std::size_t h2 = std::hash<int> {}(channel);
return h1 ^ (h2 << 1);
}

VstAudioClient::~VstAudioClient()
{
if (!m_pluginComponent) {
Expand All @@ -49,13 +56,43 @@ void VstAudioClient::init(AudioPluginType type, VstPluginPtr plugin, audioch_t a
m_audioChannelsCount = audioChannelsCount;
}

void VstAudioClient::loadSupportedParams()
{
TRACEFUNC;

IF_ASSERT_FAILED(m_pluginPtr) {
return;
}

PluginControllerPtr controller = m_pluginPtr->controller();
IF_ASSERT_FAILED(controller) {
return;
}

int paramCount = controller->getParameterCount();

for (int i = 0; i < paramCount; ++i) {
PluginParamInfo info;
controller->getParameterInfo(i, info);
m_pluginParamInfoMap.emplace(info.id, std::move(info));
}
}

bool VstAudioClient::handleEvent(const VstEvent& event, const samples_t sampleOffset)
{
ensureActivity();

VstEvent& ev = const_cast<VstEvent&>(event);
ev.sampleOffset = sampleOffset;

if (ev.type == VstEvent::kNoteOnEvent) {
size_t key = noteEventKey(ev.noteOn.pitch, ev.noteOn.channel);
m_playingNotes.insert_or_assign(key, ev);
} else if (ev.type == VstEvent::kNoteOffEvent) {
size_t key = noteEventKey(ev.noteOff.pitch, ev.noteOff.channel);
m_playingNotes.erase(key);
}

if (m_eventList.addEvent(ev) == Steinberg::kResultTrue) {
return true;
}
Expand All @@ -68,6 +105,8 @@ bool VstAudioClient::handleParamChange(const ParamChangeEvent& param, const samp
ensureActivity();
addParamChange(param, sampleOffset);

m_playingParams.insert(param.paramId);

return true;
}

Expand Down Expand Up @@ -122,16 +161,55 @@ muse::audio::samples_t VstAudioClient::process(float* output, samples_t samplesP

void VstAudioClient::flush()
{
flushBuffers();
allNotesOff();

disableActivity();
}

void VstAudioClient::allNotesOff()
{
if (m_playingNotes.empty() && m_playingParams.empty()) {
return;
}

flushBuffers();

m_eventList.clear();
m_paramChanges.clearQueue();

if (m_allNotesOffParam.has_value()) {
addParamChange(m_allNotesOffParam.value(), 0);
for (const auto& pair : m_playingNotes) {
const VstEvent& noteOn = pair.second;

VstEvent noteOff;
noteOff.type = VstEvent::kNoteOffEvent;
noteOff.ppqPosition = 0;
noteOff.sampleOffset = 0;
noteOff.busIndex = noteOn.busIndex;
noteOff.flags = noteOn.flags;
noteOff.noteOff.noteId = noteOn.noteOn.noteId;
noteOff.noteOff.channel = noteOn.noteOn.channel;
noteOff.noteOff.pitch = noteOn.noteOn.pitch;
noteOff.noteOff.tuning = noteOn.noteOn.tuning;
noteOff.noteOff.velocity = noteOn.noteOn.velocity;

m_eventList.addEvent(noteOff);
}

for (PluginParamId id : m_playingParams) {
auto intoIt = m_pluginParamInfoMap.find(id);
if (intoIt == m_pluginParamInfoMap.end()) {
continue;
}

ParamChangeEvent paramOff;
paramOff.paramId = id;
paramOff.value = intoIt->second.defaultNormalizedValue;

addParamChange(paramOff, 0);
}

m_playingNotes.clear();
m_playingParams.clear();
}

void VstAudioClient::setMaxSamplesPerBlock(unsigned int samples)
Expand Down Expand Up @@ -302,7 +380,6 @@ void VstAudioClient::updateProcessSetup()

setUpProcessData();
flushBuffers();
loadAllNotesOffParam();

ensureActivity();
}
Expand Down Expand Up @@ -447,20 +524,6 @@ void VstAudioClient::flushBuffers()
}
}

void VstAudioClient::loadAllNotesOffParam()
{
if (m_allNotesOffParam.has_value()) {
return;
}

ParamsMapping mapping = paramsMapping({ Steinberg::Vst::kCtrlAllNotesOff });
if (mapping.empty()) {
return;
}

m_allNotesOffParam = ParamChangeEvent { mapping.begin()->second, 1 };
}

void VstAudioClient::addParamChange(const ParamChangeEvent& param, const samples_t sampleOffset)
{
Steinberg::int32 dummyIdx = 0;
Expand Down
11 changes: 8 additions & 3 deletions src/framework/vst/internal/vstaudioclient.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,16 @@ class VstAudioClient

void init(muse::audio::AudioPluginType type, VstPluginPtr plugin, muse::audio::audioch_t audioChannelsCount = 2);

void loadSupportedParams();

bool handleEvent(const VstEvent& event, const audio::samples_t sampleOffset);
bool handleParamChange(const ParamChangeEvent& param, const audio::samples_t sampleOffset);
void setVolumeGain(const muse::audio::gain_t newVolumeGain);

muse::audio::samples_t process(float* output, muse::audio::samples_t samplesPerChannel);

void flush();
void allNotesOff();

void setMaxSamplesPerBlock(unsigned int samples);
void setSampleRate(unsigned int sampleRate);
Expand Down Expand Up @@ -75,7 +78,6 @@ class VstAudioClient

void flushBuffers();

void loadAllNotesOffParam();
void addParamChange(const ParamChangeEvent& param, const audio::samples_t sampleOffset);

bool m_isActive = false;
Expand All @@ -94,12 +96,15 @@ class VstAudioClient
VstProcessData m_processData;
VstProcessContext m_processContext;

std::unordered_map<size_t, VstEvent> m_playingNotes;
std::unordered_set<PluginParamId> m_playingParams;

std::unordered_map<PluginParamId, PluginParamInfo> m_pluginParamInfoMap;

bool m_needUnprepareProcessData = false;

muse::audio::AudioPluginType m_type = muse::audio::AudioPluginType::Undefined;
muse::audio::audioch_t m_audioChannelsCount = 0;

std::optional<ParamChangeEvent> m_allNotesOffParam;
};
}

Expand Down

0 comments on commit fcf42f3

Please sign in to comment.