olilarkin
03-16-2010, 02:13 PM
i am making a small midi triggered looper plugin and it seems that the MIDI timing works in reaper but not cubase. I have uploaded a video to demonstrate + code. Has anyone experienced this or know what it might be? I did a similar thing with just the VST sdk and got good timing in cubase.
The plugin should loop the last beat's worth of audio when a midi note is received.
GetSamplesPerBeat() seems to return the same on each host, but with Cubase the timing is all over the place. I find it very hard to debug these kinds of issues. Any tips would be much appreciated.
oli
http://www.olilarkin.co.uk/temp/midiproblem/
void Looper::ProcessDoubleReplacing(double** inputs, double** outputs, int nFrames)
{
// Mutex is already locked for us.
double* in1 = inputs[0];
double* in2 = inputs[1];
double* out1 = outputs[0];
double* out2 = outputs[1];
int samplesPerLoop = floor(GetSamplesPerBeat());
for (int offset = 0; offset < nFrames; ++offset, ++in1, ++in2, ++out1, ++out2)
{
while (!mMidiQueue.Empty())
{
IMidiMsg* pMsg = mMidiQueue.Peek();
if (pMsg->mOffset > offset) break;
// Handle the MIDI message.
int status = pMsg->StatusMsg();
switch (status)
{
case IMidiMsg::kNoteOn:
case IMidiMsg::kNoteOff:
int velocity = pMsg->Velocity();
//Note On
if (status == IMidiMsg::kNoteOn && velocity)
{
//mGain = 1.;
mNote = true;
}
//Note Off
else
{
mNote = false;
//mGain = 0.;
}
break;
default:
break;
}
mMidiQueue.Remove();
}
if(mNote)
{
*out1 = mBuffer[mCount2++];
mCount2 %= samplesPerLoop;
}
else
{
mCount2 = 0;
mBuffer[mCount++] = *in1;
mCount %= samplesPerLoop;
*out1 = *in1;
}
*out2 = *out1;
}
mMidiQueue.Flush(nFrames);
}
void Looper::Reset()
{
TRACE;
IMutexLock lock(this);
mMidiQueue.Resize(GetBlockSize());
mSampleRate = GetSampleRate();
mSamplePeriod = 1./mSampleRate;
mCount = 0;
}
The plugin should loop the last beat's worth of audio when a midi note is received.
GetSamplesPerBeat() seems to return the same on each host, but with Cubase the timing is all over the place. I find it very hard to debug these kinds of issues. Any tips would be much appreciated.
oli
http://www.olilarkin.co.uk/temp/midiproblem/
void Looper::ProcessDoubleReplacing(double** inputs, double** outputs, int nFrames)
{
// Mutex is already locked for us.
double* in1 = inputs[0];
double* in2 = inputs[1];
double* out1 = outputs[0];
double* out2 = outputs[1];
int samplesPerLoop = floor(GetSamplesPerBeat());
for (int offset = 0; offset < nFrames; ++offset, ++in1, ++in2, ++out1, ++out2)
{
while (!mMidiQueue.Empty())
{
IMidiMsg* pMsg = mMidiQueue.Peek();
if (pMsg->mOffset > offset) break;
// Handle the MIDI message.
int status = pMsg->StatusMsg();
switch (status)
{
case IMidiMsg::kNoteOn:
case IMidiMsg::kNoteOff:
int velocity = pMsg->Velocity();
//Note On
if (status == IMidiMsg::kNoteOn && velocity)
{
//mGain = 1.;
mNote = true;
}
//Note Off
else
{
mNote = false;
//mGain = 0.;
}
break;
default:
break;
}
mMidiQueue.Remove();
}
if(mNote)
{
*out1 = mBuffer[mCount2++];
mCount2 %= samplesPerLoop;
}
else
{
mCount2 = 0;
mBuffer[mCount++] = *in1;
mCount %= samplesPerLoop;
*out1 = *in1;
}
*out2 = *out1;
}
mMidiQueue.Flush(nFrames);
}
void Looper::Reset()
{
TRACE;
IMutexLock lock(this);
mMidiQueue.Resize(GetBlockSize());
mSampleRate = GetSampleRate();
mSamplePeriod = 1./mSampleRate;
mCount = 0;
}