Hello,
I am trying to sent noteOn en noteOffs from a midi effect plugin that I am making. The basic idea is to translate a midi cc message into notes.
The noteOn works fine, but the noteOff doesn’t. Whatever I tried, nothing worked so far. Debugging shows that the noteOff is created and added to the buffer as is the noteOn. The noteOn works, but the noteOff does not (when running it in Logic). Here is the code:
First the function that creates the noteOff:
void StripToNotesAudioProcessor::SentNotesOff(juce::MidiBuffer& processedMidi, int exceptNote, int time)
{
//loop through array for all notes
for(int i=0;i<MAX_NOTES;i++)
{
//if note was pressed, the channel was set.
if(notePressedChannel[i]>0 && i!=exceptNote)
{
auto message = juce::MidiMessage::noteOff(notePressedChannel[i],noteValues[i]);
notePressedChannel[i]=-1;
processedMidi.addEvent(message, time);
}
}
}
And here the function that calls the SentNotesOff function and creates the new noteOn:
void StripToNotesAudioProcessor::processBlock (juce::AudioBuffer<float>& buffer, juce::MidiBuffer& midiMessages)
{
// A pure MIDI plugin shouldn't be provided any audio data
jassert (buffer.getNumChannels() == 0);
// however we use the buffer to get timing information
auto numSamples = buffer.getNumSamples();
buffer.clear();
//create a new buffer
juce::MidiBuffer processedMidi;
//loop through the incoming messages
for(const auto metadata : midiMessages)
{
auto message = metadata.getMessage();
auto time = metadata.samplePosition;
// in case the message is a controller message of the specified controller number,
// replace it with a noteOn message.
if(message.isController() && message.getControllerNumber() == midiCC)
{
auto ccval = message.getControllerValue();
auto channel = message.getChannel();
for(int i=0 ; i < numberOfZones+1 ;i++)
{
if(ccval<1)
{
//if ccval is 0, then stop any note from sounding
SentNotesOff(processedMidi,-1);
break;
}
//if ccval is in range according to spliValues array, start the note
if(ccval < splitValues[i])
{
//only do something if the same note is not already pressed
if(notePressedChannel[i] != channel)
{
//first send noteOff for previous note.
SentNotesOff(processedMidi, i, time);
//create new noteOn
message = juce::MidiMessage::noteOn(channel,
noteValues[i-1],
noteVelocity);
notePressedChannel[i] = channel;
}
//stop the loop as soon as a range was valid
break;
}
}
}
//add the noteOn event to the buffer
processedMidi.addEvent(message,time);
}
//swap the original buffer with the new created one
midiMessages.swapWith(processedMidi);
}