fbpx
Skip to main content

MIDI Forum

Does Microsoft GS W...
 
Notifications
Clear all

Does Microsoft GS Wavetable Synth have its own timer and store the notes on messages for playback?

6 Posts
4 Users
0 Reactions
11 K Views
Steve
Posts: 6
Active Member
Topic starter
 

First of all...thanks to everyone for answering my previous questions and putting up with my arrogant attitude. I have been humbled by your empathy and friendly assistance.

I've attached a simple MIDI file that Windows Media Player finds acceptable. Now I want to play it by directly using the built-in Microsoft GS Wavetable Synth from Visual Studio. What are the steps? Do I simply read the file and send the track messages to the MidiSynthesizer: https://docs.microsoft.com/en-us/uwp/api/windows.devices.midi.midisynthesizer Does it store the messages so that I can send it the Start message and it will play it or do I have to send it all the messages each time I want to play the file?

In other words do I read the file and send the track messages to the MidiSynthesizer as I read it and then send the Start message? Does the MidiSynthesizer store and process the messages or do I have to develop my own timers to send the messages at the proper time? Right now I have developed several timers to send the messages at the proper time, but I'm having difficulties keeping them in synch.

Also, upon inspection the Note On Message doesn't include the Delta-Time. So, how do I specify the Delta-Time for each message?

 
Posted : 15/12/2021 2:04 am
Pedro Lopez-Cabanillas
Posts: 154
Estimable Member
 

No, The "Microsoft SG Wavetable Synth" is a MIDI synthesizer, not a MIDI sequencer.

There is a Windows built-in MIDI Sequencer in the Win32 API, but I don't know if MS offers an UWP wrapper. The Win32 MIDI Stream API is documented, and didn't change for the last 30 years. It is not limited to the "Microsoft SG Wavetable Synth", you may use any other MIDI OUT port available.

https://docs.microsoft.com/en-us/windows/win32/api/mmeapi/nf-mmeapi-midistreamopen

See also: https://docs.microsoft.com/en-us/windows/win32/multimedia/musical-instrument-digital-interface--midi

Here is an article about it:

http://midi.teragonaudio.com/tech/stream.htm

Of course, you may write your own sequencer instead of using the MIDI Stream API.

 
Posted : 15/12/2021 3:24 am
Bavi_H
Posts: 267
Reputable Member
 

[quotePost id=12733]upon inspection the Note On Message doesn't include the Delta-Time. So, how do I specify the Delta-Time for each message?[/quotePost]
Although most MIDI sequencer software will show a note as a single event that contains a duration value, be aware that the actual events in the MIDI file (and the actual messages sent to a MIDI port) use one message to start the note and another message to end the note:

In MIDI, you start a note with a Note On message with non-zero velocity.
You end a note with a Note Off message or a Note On message with zero velocity.

Your example MIDI file only contains note messages that start notes on Channel 10. It's true that when sending Channel 10 percussion notes to a MIDI device, most devices will produce the correct drum sounds and not care if the messages to end the notes are missing. However, you are supposed to always include a message to end each note, so that anything else that processes the MIDI file or the MIDI port's message stream can tell the note ends.

MIDI 1.0 Detailed Specification, Appendix section "Assignment of Note On/Off Commands" on PDF page 67 / printed page A-4: "The transmitter [...] must send a corresponding Note Off message for every Note On sent."

General MIDI System Level 1 Developer Guidelines section "Response to Note-off on Channel 10 (Percussion)" on PDF page 19 / printed page 15: "The MIDI Specification requires that all Note-On commands have a corresponding Note-Off command, and it is assumed that all MIDI transmitters will comply with this requirement"

 
Posted : 15/12/2021 4:37 am
Geoff
Posts: 1047
Noble Member
 

I assume that it's the GS Wavetable Synth we're talking about here. Not 'SG'.

I've had a quick look at some of the code/notes regarding the API and I see that the low level routines for dealing with packets of data for midi messages specifically say that for any packets being sent OUT via the midi port, any timestamp data will be disregarded, which suggestes to me that the system assumes that data will be presented to the port ONLY when it is due to be sent, and it would normally be sent immed. So there may be a buffer to handle a number of items all being sent at once, but no more than that.

When I was writing my own 'sequencer' prog, my prog handled everything to do with timing, and ran it's own clock, which generated it's own version of the delta time, which would be modified according to tempo, etc.

All the data, midi messages, were ordered by time. The prog stepped through the list item by item. For each one, it compared the delta time of the message with the current time and sent the data ONLY if it was due, if it was not due, it waited until it was due.

For my own purposes I store the note data as note ON, with duration (and discard the note OFF message). I've seen other systems that do the same thing. I therefore need to keep a separate list of 'notes in progress' to consult for note OFF event, but I needed to know how many notes were active at any one time for my own purposes anyway. This list always seemed to get back down to zero at the end of the file! If it didn't, then something has gone wrong.

Geoff

 
Posted : 15/12/2021 12:30 pm
Steve
Posts: 6
Active Member
Topic starter
 

Thank you everyone for the great responses. From the available options I think I will continue to improve my existing implementation of a Midi Sequencer for Universal Windows Programs in C# UWP. I initially made the mistake of using an object-oriented approach and created a class to handle each channel-note combination for my current implementation. It works nicely; however, trying to keep them in synch is a nightmare because unless I force each instance onto a new CPU one note will always play before then next even if they have the exact same Delta-Time...and I only have 7 CPUs on my system so I would run out of CPUs for anything except a simple drum track.

So, I'm going to run everything on a single timer and change the interval each time...that way if another note needs to be played at the same time I can check for it and play it right away. And, I was initially setting the timer interval to the calculated CPU Ticks from Delta-Time, Division, and Tempo; however, the overhead from processing the timer start and Timer_Tick events as well as the time it takes to send the midi message will cause the song to be off by a tiny random amount, but just enough to paint myself into a corner so that I can't sequence the midi events with say a wave audio file. I'll fix this by delaying the start of the midi sequence for a few seconds and pre-calculate and build an array of timer intervals in advance to ensure that the timer events arrive at the correct time regardless of how long it takes to process the current notes.

 
Posted : 16/12/2021 8:08 am
Pedro Lopez-Cabanillas
Posts: 154
Estimable Member
 

Microsoft Officially Deprecates UWP

 
Posted : 18/12/2021 1:26 am
Share: