I have an odd issue with Cubase hosting a midi generating plugin as VST3. This works fine in Ableton Live and in Studio One. I have a feeling it is in int numSamples = buffer.getNumSamples();
but it did work when I was using the deprecated getCurrentPosition()
. I updated the code to use getPosition()
and it now puts out exactly 11 notes per step. Which is weird. I’m still learning and trying to debug but I am on an M1 and can’t seem to get the values passed back to the debugger in xcode.
The only things that changed in the code is as follows:
if (playHead != nullptr)
{
auto* audioPlayHead = playHead.load();
if (audioPlayHead != nullptr)
{
juce::AudioPlayHead::CurrentPositionInfo posInfo;
if (audioPlayHead->getCurrentPosition(posInfo))
{
currentTempo = posInfo.bpm;
transportIsPlaying = posInfo.isPlaying;
ppqPosition = posInfo.ppqPosition;
if (ppqPosition < 0.01) // if the playhead has returned to the beginning
{
currentStep = 0;
currentNote = -1;
}
}
}
}
And the new code:
void MidiSequencerAudioProcessor::processBlock(juce::AudioBuffer<float>& buffer, juce::MidiBuffer& midiMessages)
{
buffer.clear();
juce::MidiBuffer outputMidi;
int numSamples = buffer.getNumSamples();
double currentTempo = 120.0;
bool transportIsPlaying = false;
double ppqPosition = 0;
if (playHead != nullptr)
{
auto* audioPlayHead = playHead.load();
if (audioPlayHead != nullptr)
{
auto positionInfo = audioPlayHead->getPosition();
if (positionInfo) // Check if positionInfo is available
{
// Extract bpm if available
if (auto bpm = positionInfo->getBpm())
{
currentTempo = *bpm;
}
transportIsPlaying = positionInfo->getIsPlaying();
// Extract ppqPosition if available
if (auto ppqPos = positionInfo->getPpqPosition())
{
ppqPosition = *ppqPos;
}
if (ppqPosition < 0.01) // if the playhead has returned to the beginning
{
currentStep = 0;
currentNote = -1;
}
}
}
}
double stepDuration = 60.0 / (currentTempo * stepsPerBeat);
samplesPerStep = static_cast<int>(getSampleRate() * stepDuration);
for (int sample = 0; sample < numSamples; ++sample)
{
if (transportIsPlaying && sample % samplesPerStep == 0)
{
// If there's a note playing, send a note off event
if (currentNote != -1)
{
outputMidi.addEvent(juce::MidiMessage::noteOff(1, currentNote), sample);
currentNote = -1;
}
// If the step is triggered, send a note on event
if (stepTriggers[currentStep])
{
currentNote = stepNotes[currentStep];
outputMidi.addEvent(juce::MidiMessage::noteOn(1, currentNote, (juce::uint8)127), sample);
if (velocityOutputEnabled) {
auto velocity = getStepVelocity(currentStep);
outputMidi.addEvent(juce::MidiMessage::noteOn(1, currentNote, (juce::uint8)velocity), sample);
}
if (cc1OutputEnabled) {
auto cc1Value = getStepCC1(currentStep);
outputMidi.addEvent(juce::MidiMessage::controllerEvent(1, cc1Channel, cc1Value), sample); }
if (cc2OutputEnabled) {
auto cc2Value = getStepCC2(currentStep);
outputMidi.addEvent(juce::MidiMessage::controllerEvent(1, cc2Channel, cc2Value), sample); }
}
sendChangeMessage();
}
}
midiMessages.swapWith(outputMidi);
}
Tested versions are Cubase 12 and 13.