|
|
@@ -15,6 +15,7 @@ |
|
|
|
*/
|
|
|
|
|
|
|
|
#include "DistrhoPluginKars.hpp"
|
|
|
|
#include "DistrhoPluginUtils.hpp"
|
|
|
|
|
|
|
|
START_NAMESPACE_DISTRHO
|
|
|
|
|
|
|
@@ -117,137 +118,6 @@ void DistrhoPluginKars::activate() |
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Handy class to help keep audio buffer in sync with incoming MIDI events.
|
|
|
|
To use it, create a local variable (on the stack) and call nextEvent() until it returns false.
|
|
|
|
@code
|
|
|
|
for (AudioMidiSyncHelper amsh(outputs, frames, midiEvents, midiEventCount); amsh.nextEvent();)
|
|
|
|
{
|
|
|
|
float* const outL = amsh.outputs[0];
|
|
|
|
float* const outR = amsh.outputs[1];
|
|
|
|
|
|
|
|
for (uint32_t i=0; i<amsh.midiEventCount; ++i)
|
|
|
|
{
|
|
|
|
const MidiEvent& ev(amsh.midiEvents[i]);
|
|
|
|
// ... do something with the midi event
|
|
|
|
}
|
|
|
|
|
|
|
|
renderSynth(outL, outR, amsh.frames);
|
|
|
|
}
|
|
|
|
@endcode
|
|
|
|
|
|
|
|
Some important notes when using this class:
|
|
|
|
1. MidiEvent::frame retains its original value, but it is useless, do not use it.
|
|
|
|
2. The class variables names are be the same as the default ones in the run function.
|
|
|
|
Keep that in mind and try to avoid typos. :)
|
|
|
|
*/
|
|
|
|
class AudioMidiSyncHelper {
|
|
|
|
public:
|
|
|
|
/** Parameters from the run function, adjusted for event sync */
|
|
|
|
float** outputs;
|
|
|
|
uint32_t frames;
|
|
|
|
const MidiEvent* midiEvents;
|
|
|
|
uint32_t midiEventCount;
|
|
|
|
|
|
|
|
/**
|
|
|
|
Constructor, using values from the run function.
|
|
|
|
*/
|
|
|
|
AudioMidiSyncHelper(float** const o, uint32_t f, const MidiEvent* m, uint32_t mc)
|
|
|
|
: outputs(o),
|
|
|
|
frames(0),
|
|
|
|
midiEvents(m),
|
|
|
|
midiEventCount(0),
|
|
|
|
remainingFrames(f),
|
|
|
|
remainingMidiEventCount(mc),
|
|
|
|
totalFramesUsed(0) {}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Process a batch of events untill no more are available.
|
|
|
|
You must not read any more values from this class after this function returns false.
|
|
|
|
*/
|
|
|
|
bool nextEvent()
|
|
|
|
{
|
|
|
|
// nothing else to do
|
|
|
|
if (remainingFrames == 0)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// initial setup, need to find first MIDI event
|
|
|
|
if (totalFramesUsed == 0)
|
|
|
|
{
|
|
|
|
// no MIDI events at all in this process cycle
|
|
|
|
if (remainingMidiEventCount == 0)
|
|
|
|
{
|
|
|
|
frames = remainingFrames;
|
|
|
|
remainingFrames = 0;
|
|
|
|
totalFramesUsed += frames;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// render audio until first midi event, if needed
|
|
|
|
if (const uint32_t firstEventFrame = midiEvents[0].frame)
|
|
|
|
{
|
|
|
|
frames = midiEvents[0].frame;
|
|
|
|
remainingFrames -= frames;
|
|
|
|
totalFramesUsed += frames;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for (uint32_t i=0; i<DISTRHO_PLUGIN_NUM_OUTPUTS; ++i)
|
|
|
|
outputs[i] += frames;
|
|
|
|
}
|
|
|
|
|
|
|
|
// no more MIDI events available
|
|
|
|
if (remainingMidiEventCount == 0)
|
|
|
|
{
|
|
|
|
frames = remainingFrames;
|
|
|
|
midiEvents = nullptr;
|
|
|
|
midiEventCount = 0;
|
|
|
|
remainingFrames = 0;
|
|
|
|
totalFramesUsed += frames;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// if there were midi events before, increment pointer
|
|
|
|
if (midiEventCount != 0)
|
|
|
|
midiEvents += midiEventCount;
|
|
|
|
|
|
|
|
const uint32_t firstEventFrame = midiEvents[0].frame;
|
|
|
|
DISTRHO_SAFE_ASSERT_RETURN((firstEventFrame - frames) < remainingFrames, false);
|
|
|
|
|
|
|
|
midiEventCount = 1;
|
|
|
|
while (midiEventCount < remainingMidiEventCount)
|
|
|
|
{
|
|
|
|
if (midiEvents[midiEventCount].frame == firstEventFrame)
|
|
|
|
++midiEventCount;
|
|
|
|
else
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (totalFramesUsed != 0)
|
|
|
|
{
|
|
|
|
for (uint32_t i=0; i < midiEventCount; ++i)
|
|
|
|
{
|
|
|
|
DISTRHO_SAFE_ASSERT_UINT2_BREAK(midiEvents[i].frame - totalFramesUsed == 0,
|
|
|
|
midiEvents[i].frame, totalFramesUsed);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
frames = remainingFrames - firstEventFrame;
|
|
|
|
remainingFrames -= frames;
|
|
|
|
remainingMidiEventCount -= midiEventCount;
|
|
|
|
totalFramesUsed += frames;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
/** @internal */
|
|
|
|
uint32_t remainingFrames;
|
|
|
|
uint32_t remainingMidiEventCount;
|
|
|
|
uint32_t totalFramesUsed;
|
|
|
|
};
|
|
|
|
|
|
|
|
void DistrhoPluginKars::run(const float**, float** outputs, uint32_t frames, const MidiEvent* midiEvents, uint32_t midiEventCount)
|
|
|
|
{
|
|
|
|
uint8_t note, velo;
|
|
|
|