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

Midi playing with Timer

Nov 19, 2016 at 6:48 AM

I've recently been fiddling around with creating a multitrack wave player using NAudio.
(Tracks are mixed using a customized MixingSampleProvider that also incorporates track pan, volume, etc.)

Since I finally got everything working reasonably well through WaveOut, I'm thinking about adding Midi since NAudio provides excellent Midi file event handling capabilities.
(Incidentally, using Mark's PianoRoll (Part2) as a base, I've gotten the Midi data adequately visualized.)

But I'm not sure exactly how to play the Midi in synch with my WaveOut...
I imagine it will involve a timer (I'm already implementing a custom timer which I use for time display and movement of a play position marker), and sending MidiMessage.StartNote, etc. to the designated MidiOut device?
If so, any ideas on the best way to go about it?

My timer already updates a "PlayPosition" property (in milliseconds), so I have that.
So, my first thought is to cycle through each midi NoteOn event, and play it if the PlayPosition is between its AbsoluteTime and the next noteoff, but that seems like the most poorly efficient way to do it.

There's a much better way, isn't there...?
Nov 21, 2016 at 8:47 AM
Edited Nov 21, 2016 at 8:48 AM
Ok, somewhat later I figured out at least one better way which when crudely implemented seems to work properly....

I keep a "CurrentIndex" for the MidiEvents, and every time the timer ticks, it checks if MidiEvent(CurrentIndex).AbsoluteTime is < or = the PlayPosition.
If it is, it sends the MidiMessage.StartNote for that note, and increments the CurrentIndex by 1.
So, next timer tick, it simply checks the incremented MidiEvent(CurrentIndex), and so on.

(Now just have to modify that to include program changes, and especially note off events...)

I assume in theory that's that the best way to do it...?
Dec 3, 2016 at 10:54 PM
I'm afraid NAudio has no built-in sequencer, but you might want to have a look in the WPF demo's drum machine sample to see how I attempted to schedule drums to happen at the right time. It's probably not the perfect solution, but it does work reasonable well.
Dec 4, 2016 at 7:45 AM

I've been looking over and studying your drum machine sample and borrowed parts of it to try to get it to play SoundFont samples.
At this point I have it where the midi notes properly trigger playing of samples (that is, at the right times), but the samples aren't getting looped properly :-(
This is to say, the samples stutter for the duration of each note. Obviously a problem with how Im looping them...

I'll try to post some code later...
I've been translating all NAudio code to VB for my own use, so when I post code, is VB ok, or should I translate to C#?