WAVEFORMAT_MIDI_MESSAGE (Compact 7)

3/12/2014

This structure specifies the timing information of a MIDI file.

Syntax

typedef struct _WAVEFORMAT_MIDI_MESSAGE {
UINT32 DeltaTicks;
DWORD MidiMsg;
} WAVEFORMAT_MIDI_MESSAGE;

Members

  • DeltaTicks
    Number of ticks to wait before playing a message after the previous message has finished playing.
  • MidiMsg
    32-bit MIDI message value that is consistent with the MIDI messages used in desktop-based operating systems. The message is packed into a DWORD value with the first byte of the message in the low-order byte range, as indicated in the following table.

    Word Byte Usage

    High

    High-order

    Must be 0.

    High

    Low-order

    The second byte of MIDI data (optional).

    Low

    High-order

    The first byte of MIDI data (optional).

    Low

    Low-order

    The MIDI status.

    The two MIDI data bytes are optional depending on the MIDI status byte. When a series of messages have the same status byte, you can omit the status byte from each message after the first in the series, creating a running status. Running status messages should be packed as indicated in the following table.

    Word Byte Usage

    High

    High-order

    Must be 0.

    High

    Low-order

    Not used.

    Low

    High-order

    The second byte of MIDI data (optional).

    Low

    Low-order

    The first byte of MIDI data.

    The high-order byte of the DWORD value is also used for proprietary messages by storing into the DWORD value one of the message values described in the following table.

    Value Description

    MIDI_MESSAGE_UPDATETEMPO

    Tells the MIDI player to update the tempo based on the rate specified within the MIDI file. The lower 24 bits (bits 23-0) of this value contain the new setting to be used as m_USecPerQuarterNote.

    MIDI_MESSAGE_FREQGENON

    Starts playing a sine wave at the specified frequency. Bits 15-0 contain the value of the frequency to be played, and bits 22-16 contain the 7-bit velocity (volume) to be used. (A velocity of 0 indicates the frequency should be turned off.)

    MIDI_MESSAGE_FREQGENOFF

    Stops playing the specified frequency. Bits 15-0 contain the frequency value to be stopped.

Code Example

Sample code to play a local busy (reorder) tone 20 times. This tone is comprised of the frequencies 480 & 620 in a played in a 3 seconds on/2 seconds off cadence.

Important

For readability, the following code example does not contain security checking or error handling. Do not use the following code in a production environment.

#define DEFINE_GUIDS 1
#include "windows.h"
#include "stdio.h"
#include "wfmtmidi.h"
/*
DTMF frequencies:
DTMF stands for Dual Tone Multi Frequency. These are the tones used 
for key presees on a telephone touchpad. The tone of the button is the
sum of the column and row tones. The ABCD keys do not exist on standard
telephones.
 Frequency 1
1209133614771633
------------------------
697 |123A
770 |456B
Frequency 2852 |789C
941 |*0#D
Frequencies of other telephone tones
TypeHzOnOff
-------------------------------------------
Dial Tone 350 &400------
Busy Signal480 &6200.50.5
Toll Congestion 480 &6200.20.3
Ringback (Normal)440 &4802.04.0
Ringback (PBX)440 &4801.54.5
Reorder (Local) 480 &6203.02.0
Invalid Number200 &400
End Call Warning1400 & 20600.10.1
End Call2450 & 2600------
*/
HANDLE hEvent;
void CALLBACK waveOutProc(
 HWAVEOUT hwo,
 UINT uMsg,
 DWORD dwInstance,
 DWORD dwParam1,
 DWORD dwParam2
) {
if (uMsg==WOM_DONE) {
 SetEvent(hEvent);
}
return;
}
int _tmain(int argc, TCHAR *argv[]) {
hEvent=CreateEvent( NULL,TRUE,FALSE,NULL);
WAVEFORMAT_MIDI wfm;
memset(&wfm,0,sizeof(wfm));
wfm.wfx.wFormatTag=WAVE_FORMAT_MIDI;
wfm.wfx.nChannels=1;
wfm.wfx.nSamplesPerSec=32;
wfm.wfx.nAvgBytesPerSec=32;
wfm.wfx.nBlockAlign=sizeof(WAVEFORMAT_MIDI_MESSAGE);
wfm.wfx.wBitsPerSample=16;
wfm.wfx.cbSize=WAVEFORMAT_MIDI_EXTRASIZE;
wfm.USecPerQuarterNote=9600000; // Force each tick to be 1/10 sec
MMRESULT Result;
HWAVEOUT hWaveOut;
Result = waveOutOpen(&hWaveOut, WAVE_MAPPER,
(LPWAVEFORMATEX)&wfm, (DWORD)waveOutProc,
0, CALLBACK_FUNCTION);
if (Result!=MMSYSERR_NOERROR) {
 return -1;
}
WAVEFORMAT_MIDI_MESSAGE MidiMessage[5];
MidiMessage[0].DeltaTicks=0;
MidiMessage[0].MidiMsg=0x203F0000 | 480;
MidiMessage[1].DeltaTicks=0;
MidiMessage[1].MidiMsg=0x203F0000 | 620;
MidiMessage[2].DeltaTicks=2;
MidiMessage[2].MidiMsg=0x303F0000 | 480;
MidiMessage[3].DeltaTicks=0;
MidiMessage[3].MidiMsg=0x303F0000 | 620;
MidiMessage[4].DeltaTicks=3;
MidiMessage[4].MidiMsg=0; // Dummy msg, does nothing
WAVEHDR WaveHdr;
WaveHdr.lpData = (LPSTR)&MidiMessage;
WaveHdr.dwBufferLength = sizeof(MidiMessage);
WaveHdr.dwFlags = WHDR_BEGINLOOP|WHDR_ENDLOOP;
WaveHdr.dwLoops = 20;
Result = waveOutPrepareHeader(hWaveOut,&WaveHdr,sizeof(WaveHdr));
Result = waveOutWrite(hWaveOut,&WaveHdr,sizeof(WaveHdr));
WaitForSingleObject(hEvent,INFINITE);
Result = waveOutUnprepareHeader(hWaveOut,&WaveHdr,sizeof(WaveHdr));
Result = waveOutClose(hWaveOut);
return 0;
}

Requirements

Header

wfmtmidi.h

See Also

Reference

Waveform Audio Structures
MIDI
MIDI_MESSAGE_UPDATETEMPO
MIDI_MESSAGE_FREQGENON
MIDI_MESSAGE_FREQGENOFF