bool VoicerBaseUGenInternal::sendMidiNote(const int midiChannel, const int midiNote, const int velocity) throw() { const int userData = createUserData(midiChannel, midiNote); ugen_assert(userData != UGen::defaultUserData); ugen_assert(velocity >= 0); if(velocity > 0) { if(numVoices_ > 0) { const int voicesUsed = countNonstealingVoices(); if(voicesUsed >= numVoices_) { UGen stealee = chooseStealee(); if(stealee.isNotNull()) { stealee.userData = stealingUserData; stealee.steal(forcedSteal_); } } } // stop double notes, AU lab was sending two ons but only one off // stealNote(midiChannel, midiNote, false, true); // let's only do this in the Juce version.. UGen newEvent = spawnEvent(*this, currentEventIndex++, midiChannel, midiNote, velocity); if(newEvent.isNotNull()) { newEvent.userData = userData; events.add(newEvent); } } else { UGen releasee = chooseReleasee(midiChannel, midiNote); if(releasee.isNotNull()) { //releasee.userData = UGen::defaultUserData; // need to rethink why I really wanted to do this releasee.release(); } } return true; }
void VoicerUGenInternal::processBlock(bool& shouldDelete, const unsigned int blockID, const int /*channel*/) throw() { if(shouldStopAllEvents() == true) initEvents(); if(midiMessages.isEmpty() == true) { const ScopedLock sl(lock); SpawnBaseUGenInternal::processBlock(shouldDelete, blockID, -1); } else { const int blockSize = uGenOutput.getBlockSize(); MidiBuffer::Iterator iter(midiMessages); MidiMessage message(0xf4, 0.0); int samplePos = 0; int startSample = 0; const int numChannels = getNumChannels(); const int midiChannel = midiChannel_; while(iter.getNextEvent(message, samplePos) && (samplePos < blockSize)) { const ScopedLock sl(lock); if(samplePos < 0) samplePos = 0; const int numSamples = samplePos - startSample; if(numSamples > 0) { for(int channel = 0; channel < numChannels; channel++) { bufferData[channel] = proxies[channel]->getSampleData() + startSample; } mixer.prepareForBlock(numSamples, blockID + startSample, -1); mixer.setOutputs(bufferData, numSamples, numChannels); mixer.processBlock(shouldDelete, blockID + startSample, -1); } startSample = samplePos; if(message.isForChannel(midiChannel)) { if(message.isNoteOnOrOff()) { const int midiNote = message.getNoteNumber(); const int velocity = message.getVelocity(); if(velocity > 0) { if(numVoices_ > 0) { const int voicesUsed = countNonstealingVoices(); if(voicesUsed >= numVoices_) { UGen stealee = chooseStealee(); if(stealee.isNotNull()) { stealee.userData = stealingUserData; stealee.steal(forcedSteal_); } } } // stop double notes, AU lab was sending two ons but one off - seems fixed in Au Lab 2.2 //stealNote(midiChannel, midiNote, false, true); UGen newEvent = spawnEvent(*this, currentEventIndex++, midiChannel, midiNote, velocity); newEvent.userData = createUserData(midiChannel, midiNote); events.add(newEvent); } else { UGen releasee = chooseReleasee(midiChannel, midiNote); if(releasee.isNotNull()) releasee.release(); } } else if(message.isController()) { getController(message.getControllerNumber()) = message.getControllerValue() / 127.f; } else if(message.isPitchWheel()) { getPitchWheel() = (jlimit(-8191, 8191, message.getPitchWheelValue() - 8192) / 8191.f); } else if(message.isChannelPressure()) { getChannelPressure() = (message.getChannelPressureValue() / 127.f); } else if(message.isAftertouch()) { getKeyPressure(message.getNoteNumber()) = (message.getAfterTouchValue() / 127.f); } else if(message.isProgramChange()) { getProgram() = (message.getProgramChangeNumber()); } else if(message.isAllNotesOff()) { initEvents(); } } } const ScopedLock sl(lock); const int numSamples = blockSize - startSample; if(numSamples > 0) { for(int channel = 0; channel < numChannels; channel++) { bufferData[channel] = proxies[channel]->getSampleData() + startSample; } mixer.prepareForBlock(numSamples, blockID + startSample, -1); mixer.setOutputs(bufferData, numSamples, numChannels); mixer.processBlock(shouldDelete, blockID + startSample, -1); } midiMessages.clear(); events.removeNulls(); } }