This project has moved and is read-only. For the latest updates, please go here.

VST.NET does not play sequential data

Sep 1, 2010 at 6:54 PM

i've downloaded this great framework and now i am trying to create my first plugin. I want to play a sequence of notes which i read in from midi file when the host sends a noteOn event. Unfortunately it doesn't do exact what i want, it plays all the notes in de eventcollection at once instead of in sequence. i use Ableton Live as host application and Kontakt as soundsource, below is my codesnippet:

 

public void Process(VstEventCollection events)

{

 

foreach (VstEvent evnt in events)

{

 

 

if (evnt.EventType != VstEventTypes.MidiEvent) continue;

 

VstMidiEvent midiEvent = (VstMidiEvent)evnt;

 

 

VstMidiEvent mappedEvent = null;

 

System.Diagnostics.

Debug.WriteLine("Receiving Midi Event:" + midiEvent.MidiData[0], "VST.NET");

 

if (((midiEvent.MidiData[0] & 0xF0) == 0x90))

{

 

MidiFile mf = new MidiFile(@"c:\temp\v1cv1-acc1-cM.mid", false);

 

 

 

foreach (MidiEvent me in mf.Events[0])

{

 

if (me.CommandCode == MidiCommandCode.NoteOn)

{

 

NoteEvent ne = (NoteEvent)me;

 

NoteOnEvent noe = (NoteOnEvent) me;

 

VstTimeInfo vti = new VstTimeInfo();

 

 

mappedEvent =

new VstMidiEvent(ne.DeltaTime + int.Parse(ne.AbsoluteTime.ToString()) * int.Parse(vti.Tempo.ToString()),

noe.NoteLength,

midiEvent.NoteOffset,

 

new byte[] { 144, byte.Parse(ne.NoteNumber.ToString()), byte.Parse(ne.Velocity.ToString()) },

midiEvent.Detune,

midiEvent.NoteOffVelocity);

Events.Add(mappedEvent);

}

 

 

}

 

Does anyone have suggestions on this one?

Sep 2, 2010 at 6:40 AM
Edited Sep 2, 2010 at 6:45 AM

Assuming the midi file is longer than the time represented by one call to IVstMidiProcessor.Process...

The VST Host sets up a loop (audio engine) that repeately calls the midi and audio processor Process methods. Each time a small buffer of information is passed to plugin to process. That means that once you detect the (midi) note has been triggered to play the midi file, you have to split the entire midi file up into small parts. Each part is played everytime that the Process method is called (although you have nothing to process -except perhaps the note-off) it is a good moment to output the events. A fairly simple way to manage this is to keep track of the first note that should be played and the time that has elapsed so far. It might also be a good idea to preload the midi files (at least cache them once loaded) in order to keep performance up to speed.

Another import point is that the delta is always relavtive to the start of the current cycle. So each cycle you start with zero for the detla (not true when no notes are playing at that time, but to give you the idea).

So, bottom line is, that it is a little more complex than just opening a midi file and dumping the contents in the event collection ;-)

Hope it helps.