Plug'n Script MIDI Timing Problems.
-
- KVRist
- Topic Starter
- 33 posts since 5 Sep, 2018
Hello,
it's me again with a timing problem, lol. This time it's regarding MIDI. So i made this VSTi which transforms incoming MIDI-Data and sends it out in realtime, at least that's the plan. But for some reason it seems to have a bit of latency. In my DAW this latency is so small that i'd just not care about it, but i sent the plugin to a friend who said that the latency was so bad that he couldn't use the plugin on more than 50bpm. How can i ensure that it works the same on every machine?
Here's how the code in the processBlock-method is structured atm (sry if it's a bit too much, but maybe some of it is the problem, so better show everything i guess):
/* inputParameters */
uint8 microtonal;
/* midi */
uint8 eventChannel,sourceChannel,destChannel,note,rootVal;
int pitchWheelValue,noteModInt;
float noteMod,bendRangeDevide;
MidiEvent noteEvent,pichWheelEvent;
bool isPlaying=false;
void processBlock(BlockData& data){
for(uint m=0;m<data.inputMidiEvents.length;m++){
eventChannel=sourceChannel=0;
if(eventChannel==sourceChannel or sourceChannel==0){
noteEvent=data.inputMidiEvents[m];
if(MidiEventUtils::getType(noteEvent)==kMidiNoteOn){
note=MidiEventUtils::getNote(noteEvent);
if(isPlaying){
MidiEventUtils::setType(noteEvent,kMidiNoteOff);
MidiEventUtils::setNote(noteEvent,noteModInt);
data.outputMidiEvents.push(noteEvent);
MidiEventUtils::setType(noteEvent,kMidiNoteOn);
}
isPlaying=true;
if(note>rootVal)
noteMod=rootVal+(12.0/microtonal)*(note-rootVal);
else
noteMod=rootVal-(12.0/microtonal)*(rootVal-note);
pitchWheelValue=rint(fraction(noteMod)*8192*bendRangeDevide);
noteModInt=int(noteMod);
MidiEventUtils::setNote(noteEvent,noteModInt);
MidiEventUtils::setChannel(noteEvent,destChannel);
data.outputMidiEvents.push(noteEvent);
} else if (MidiEventUtils::getType(noteEvent)==kMidiNoteOff){
if(note==MidiEventUtils::getNote(noteEvent)){
isPlaying=false;
MidiEventUtils::setType(noteEvent,kMidiNoteOff);
MidiEventUtils::setNote(noteEvent,noteModInt);
data.outputMidiEvents.push(noteEvent);
}
}
MidiEventUtils::setPitchWheelValue(pichWheelEvent,pitchWheelValue);
data.outputMidiEvents.push(pichWheelEvent);
}
}
}
it's me again with a timing problem, lol. This time it's regarding MIDI. So i made this VSTi which transforms incoming MIDI-Data and sends it out in realtime, at least that's the plan. But for some reason it seems to have a bit of latency. In my DAW this latency is so small that i'd just not care about it, but i sent the plugin to a friend who said that the latency was so bad that he couldn't use the plugin on more than 50bpm. How can i ensure that it works the same on every machine?
Here's how the code in the processBlock-method is structured atm (sry if it's a bit too much, but maybe some of it is the problem, so better show everything i guess):
/* inputParameters */
uint8 microtonal;
/* midi */
uint8 eventChannel,sourceChannel,destChannel,note,rootVal;
int pitchWheelValue,noteModInt;
float noteMod,bendRangeDevide;
MidiEvent noteEvent,pichWheelEvent;
bool isPlaying=false;
void processBlock(BlockData& data){
for(uint m=0;m<data.inputMidiEvents.length;m++){
eventChannel=sourceChannel=0;
if(eventChannel==sourceChannel or sourceChannel==0){
noteEvent=data.inputMidiEvents[m];
if(MidiEventUtils::getType(noteEvent)==kMidiNoteOn){
note=MidiEventUtils::getNote(noteEvent);
if(isPlaying){
MidiEventUtils::setType(noteEvent,kMidiNoteOff);
MidiEventUtils::setNote(noteEvent,noteModInt);
data.outputMidiEvents.push(noteEvent);
MidiEventUtils::setType(noteEvent,kMidiNoteOn);
}
isPlaying=true;
if(note>rootVal)
noteMod=rootVal+(12.0/microtonal)*(note-rootVal);
else
noteMod=rootVal-(12.0/microtonal)*(rootVal-note);
pitchWheelValue=rint(fraction(noteMod)*8192*bendRangeDevide);
noteModInt=int(noteMod);
MidiEventUtils::setNote(noteEvent,noteModInt);
MidiEventUtils::setChannel(noteEvent,destChannel);
data.outputMidiEvents.push(noteEvent);
} else if (MidiEventUtils::getType(noteEvent)==kMidiNoteOff){
if(note==MidiEventUtils::getNote(noteEvent)){
isPlaying=false;
MidiEventUtils::setType(noteEvent,kMidiNoteOff);
MidiEventUtils::setNote(noteEvent,noteModInt);
data.outputMidiEvents.push(noteEvent);
}
}
MidiEventUtils::setPitchWheelValue(pichWheelEvent,pitchWheelValue);
data.outputMidiEvents.push(pichWheelEvent);
}
}
}
-
- KVRist
- Topic Starter
- 33 posts since 5 Sep, 2018
here's a pastebin link to the same code so it's displayed more accurately:
https://pastebin.com/186ff20a
https://pastebin.com/186ff20a
-
- KVRist
- Topic Starter
- 33 posts since 5 Sep, 2018
and here's the current state of the plugin (64bit vst2), in case it's needed:
https://we.tl/t-cmGCUwfQIS
https://we.tl/t-cmGCUwfQIS
-
- KVRist
- 222 posts since 14 Nov, 2016 from Berliner Umland
I think that the delay depends on the block size configured in your DAW. My understanding is that all you do in the loop will be sent out at the next block border. Meaning after the time in milliseconds that you have configured in the DAW as block size.
-
- KVRist
- Topic Starter
- 33 posts since 5 Sep, 2018
first of all thanks for helping me with this tricky issue
but i think it can't be the blocksize this time. my cubase is configured to have a blocksize of around 800 samples so if anyone had terrible latency due to the blocksize it would be me, lol. or does midi have a different block from audio?
-
Blue Cat Audio Blue Cat Audio https://www.kvraudio.com/forum/memberlist.php?mode=viewprofile&u=39981
- KVRAF
- 5821 posts since 8 Sep, 2004 from Paris (France)
Your code looks fine from here, so I guess it is an issue with the host latency. The buffer size is not the only parameter here: the number of buffers and the driver also make a difference. Also, are you sending these events to an external MIDI device or are they processed by a plug-in inside the DAW?