void Synthesiser::processNextBlock (AudioBuffer<floatType>& outputAudio, const MidiBuffer& midiData, int startSample, int numSamples) { // must set the sample rate before using this! jassert (sampleRate != 0); const int targetChannels = outputAudio.getNumChannels(); MidiBuffer::Iterator midiIterator (midiData); midiIterator.setNextSamplePosition (startSample); bool firstEvent = true; int midiEventPos; MidiMessage m; const ScopedLock sl (lock); while (numSamples > 0) { if (! midiIterator.getNextEvent (m, midiEventPos)) { if (targetChannels > 0) renderVoices (outputAudio, startSample, numSamples); return; } const int samplesToNextMidiMessage = midiEventPos - startSample; if (samplesToNextMidiMessage >= numSamples) { if (targetChannels > 0) renderVoices (outputAudio, startSample, numSamples); handleMidiEvent (m); break; } if (samplesToNextMidiMessage < ((firstEvent && ! subBlockSubdivisionIsStrict) ? 1 : minimumSubBlockSize)) { handleMidiEvent (m); continue; } firstEvent = false; if (targetChannels > 0) renderVoices (outputAudio, startSample, samplesToNextMidiMessage); handleMidiEvent (m); startSample += samplesToNextMidiMessage; numSamples -= samplesToNextMidiMessage; } while (midiIterator.getNextEvent (m, midiEventPos)) handleMidiEvent (m); }
void MPESynthesiserBase::renderNextBlock (AudioBuffer<floatType>& outputAudio, const MidiBuffer& inputMidi, int startSample, int numSamples) { // you must set the sample rate before using this! jassert (sampleRate != 0); MidiBuffer::Iterator midiIterator (inputMidi); midiIterator.setNextSamplePosition (startSample); bool firstEvent = true; int midiEventPos; MidiMessage m; const ScopedLock sl (noteStateLock); while (numSamples > 0) { if (! midiIterator.getNextEvent (m, midiEventPos)) { renderNextSubBlock (outputAudio, startSample, numSamples); return; } const int samplesToNextMidiMessage = midiEventPos - startSample; if (samplesToNextMidiMessage >= numSamples) { renderNextSubBlock (outputAudio, startSample, numSamples); handleMidiEvent (m); break; } if (samplesToNextMidiMessage < ((firstEvent && ! subBlockSubdivisionIsStrict) ? 1 : minimumSubBlockSize)) { handleMidiEvent (m); continue; } firstEvent = false; renderNextSubBlock (outputAudio, startSample, samplesToNextMidiMessage); handleMidiEvent (m); startSample += samplesToNextMidiMessage; numSamples -= samplesToNextMidiMessage; } while (midiIterator.getNextEvent (m, midiEventPos)) handleMidiEvent (m); }
void Synthesiser::renderNextBlock (AudioSampleBuffer& outputBuffer, const MidiBuffer& midiData, int startSample, int numSamples) { // must set the sample rate before using this! jassert (sampleRate != 0); const ScopedLock sl (lock); MidiBuffer::Iterator midiIterator (midiData); midiIterator.setNextSamplePosition (startSample); MidiMessage m (0xf4, 0.0); while (numSamples > 0) { int midiEventPos; const bool useEvent = midiIterator.getNextEvent (m, midiEventPos) && midiEventPos < startSample + numSamples; const int numThisTime = useEvent ? midiEventPos - startSample : numSamples; if (numThisTime > 0) renderVoices (outputBuffer, startSample, numThisTime); if (useEvent) handleMidiEvent (m); startSample += numThisTime; numSamples -= numThisTime; } }
void Synthesiser::renderNextBlock (AudioSampleBuffer& outputBuffer, const MidiBuffer& midiData, int startSample, int numSamples) { // must set the sample rate before using this! jassert (sampleRate != 0); MidiBuffer::Iterator midiIterator (midiData); midiIterator.setNextSamplePosition (startSample); int midiEventPos; MidiMessage m; const ScopedLock sl (lock); while (numSamples > 0) { if (! midiIterator.getNextEvent (m, midiEventPos)) { renderVoices (outputBuffer, startSample, numSamples); return; } const int samplesToNextMidiMessage = midiEventPos - startSample; if (samplesToNextMidiMessage >= numSamples) { renderVoices (outputBuffer, startSample, numSamples); handleMidiEvent (m); break; } if (samplesToNextMidiMessage < minimumSubBlockSize) { handleMidiEvent (m); continue; } renderVoices (outputBuffer, startSample, samplesToNextMidiMessage); handleMidiEvent (m); startSample += samplesToNextMidiMessage; numSamples -= samplesToNextMidiMessage; } while (midiIterator.getNextEvent (m, midiEventPos)) handleMidiEvent (m); }
DSP_EXPORT void processBlock(BlockData& data) { // smooth gain update: use begin and end values // since the actual gain is exponential, we can use the ratio between begin and end values // as an incremental multiplier for the actual gain double gainDiff=data.endParamValues[kGainParam]-data.beginParamValues[kGainParam]; double gainRatio=1; if(gainDiff!=0) gainRatio=pow(10,gainDiff/double(data.samplesToProcess)*2); uint nextEventIndex=0; for(uint i=0;i<data.samplesToProcess;i++) { // manage MIDI events while(nextEventIndex!=data.inputMidiEvents.length && data.inputMidiEvents[nextEventIndex].timeStamp<=double(i)) { handleMidiEvent(data.inputMidiEvents[nextEventIndex]); nextEventIndex++; } // compute sample value double sampleValue=0; for(uint v=0;v<activeVoicesCount;v++) { sampleValue+=voices[v].ProcessSample(); } sampleValue*=gain; // copy value to all outputs for(uint ch=0;ch<audioOutputsCount;ch++) { data.samples[ch][i]=sampleValue; } // update the gain gain*=gainRatio; } // to avoid overflow, reduce phase for all active voices for(uint i=0;i<activeVoicesCount;i++) { voices[i].ReducePhase(); } }
void ZynAddSubFxInstrument::sendControlChange( MidiControllers midiCtl, float value ) { handleMidiEvent( MidiEvent( MidiControlChange, instrumentTrack()->midiPort()->realOutputChannel(), midiCtl, (int) value, this ) ); }