Skip to content

Commit

Permalink
fix bug introduced in 0.7.2
Browse files Browse the repository at this point in the history
processBlock shouldn't be called inside reset(). So now RenderEngine calls an extra processBlock at the end. Then each  processor is responsible to look at the position info and stop MIDI.
  • Loading branch information
DBraun committed Sep 26, 2023
1 parent 4e74ffe commit ee8319f
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 19 deletions.
6 changes: 6 additions & 0 deletions Source/FaustProcessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,12 @@ void FaustProcessor::processBlock(juce::AudioSampleBuffer& buffer,
juce::MidiBuffer& midiBuffer) {
// todo: Faust should be able to use the incoming midiBuffer too.
auto posInfo = getPlayHead()->getPosition();

const bool isPlaying = posInfo->getIsPlaying();
if (!isPlaying) {
ProcessorBase::processBlock(buffer, midiBuffer);
return;
}

if (!m_compileState) {
throw std::runtime_error(
Expand Down
30 changes: 15 additions & 15 deletions Source/PluginProcessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,21 @@ void PluginProcessor::processBlock(juce::AudioSampleBuffer& buffer,
auto posInfo = getPlayHead()->getPosition();

myRenderMidiBuffer.clear();

const bool isPlaying = posInfo->getIsPlaying();

if (!isPlaying) {
// send All Notes Off MIDI message to all channels and then process it.
// todo: is it possible to send all notes midi off without doing a
// processBlock?
for (int i = 1; i < 17; i++) {
myRenderMidiBuffer.addEvent(MidiMessage::allNotesOff(i), 0);
}
myPlugin->processBlock(buffer, myRenderMidiBuffer);

ProcessorBase::processBlock(buffer, midiBuffer);
return;
}

{
auto start = *posInfo->getTimeInSamples();
Expand Down Expand Up @@ -271,21 +286,6 @@ void PluginProcessor::automateParameters(AudioPlayHead::PositionInfo& posInfo,

void PluginProcessor::reset() {
if (myPlugin.get()) {
// send All Notes Off MIDI message to all channels and then process it.
// todo: is it possible to send all notes midi off without doing a
// processBlock?
MidiBuffer midiBuffer;
for (int i = 1; i < 17; i++) {
midiBuffer.addEvent(MidiMessage::allNotesOff(i), 0);
}
AudioSampleBuffer buffer;

int numChans = std::max(myPlugin->getTotalNumInputChannels(), myPlugin->getTotalNumOutputChannels());

buffer.setSize(numChans, getBlockSize());
myPlugin->processBlock(buffer, midiBuffer);

// Now turn off all voices.
myPlugin->reset();
}

Expand Down
6 changes: 5 additions & 1 deletion Source/ProcessorBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ float ProcessorBase::getAutomationAtZeroByIndex(const int& index) {

if (index < 0 || index >= parameters.size()) {
throw std::runtime_error(
"Failed to get automation value for parameter at index: " + index);
"Failed to get automation value for parameter at index: " + std::to_string(index));
}

auto parameter = (AutomateParameterFloat*)parameters.getUnchecked(index);
Expand Down Expand Up @@ -237,6 +237,10 @@ void ProcessorBase::processBlock(juce::AudioSampleBuffer& buffer,
return;
}
auto posInfo = getPlayHead()->getPosition();
const bool isRecording = posInfo->getIsRecording();
if (!isRecording) {
return;
}

const int numberChannels = myRecordBuffer.getNumChannels();
int numSamplesToCopy =
Expand Down
5 changes: 5 additions & 0 deletions Source/RenderEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,11 @@ bool RenderEngine::render(const double renderLength, bool isBeats) {
m_positionInfo.setIsPlaying(false);
m_positionInfo.setIsRecording(false);

// processBlock once more because PluginProcessor will look at
// the playhead's isPlaying value, which was just set to false,
// to know that we should send MIDI note off messages to all channels.
m_mainProcessorGraph->processBlock(audioBuffer, renderMidiBuffer);

// restore the record-enable of the last processor.
if (m_stringDag.size()) {
auto node = m_mainProcessorGraph->getNodeForId(
Expand Down
6 changes: 3 additions & 3 deletions tests/dawdreamer_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,11 @@ def is_pytesting():

if platform.system() == "Darwin":

# append_if_exists(ALL_PLUGIN_EFFECTS, PLUGINS / "DimensionExpander.vst") # sometimes returns nan in GitHub Action
append_if_exists(ALL_PLUGIN_EFFECTS, PLUGINS / "DimensionExpander.vst")
append_if_exists(ALL_PLUGIN_EFFECTS, PLUGINS / "DimensionExpander.component")

# append_if_exists(ALL_PLUGIN_EFFECTS, PLUGINS / "RoughRider3.vst") # sometimes returns array of zeros in GitHub Action
# append_if_exists(ALL_PLUGIN_EFFECTS, PLUGINS / "RoughRider3.vst3") # sometimes outputs silence on GitHub action macOS Python 3.9
append_if_exists(ALL_PLUGIN_EFFECTS, PLUGINS / "RoughRider3.vst")
append_if_exists(ALL_PLUGIN_EFFECTS, PLUGINS / "RoughRider3.vst3")
append_if_exists(ALL_PLUGIN_EFFECTS, PLUGINS / "RoughRider3.component")

# # todo: the Valhalla Freq Echo plugins sometimes work and sometimes just output NAN.
Expand Down

0 comments on commit ee8319f

Please sign in to comment.