this one does not use midiOutReset
instead, it sets the "note off" status and resends it if it's a note
if it's not a note, it skips the wait period and goes to the next message
this allows you to select different instruments (or send other command messages) in the data stream
if we wanted to get fancy, we would use the multi-media timer, rather than Sleep
we could also allow for multiple notes to play chords, etc
;###############################################################################################
.XCREF
.NoList
INCLUDE \Masm32\Include\Masm32rt.inc
INCLUDE \Masm32\Include\WinMm.inc
INCLUDELIB \Masm32\Lib\WinMm.lib
.List
;###############################################################################################
PlayNotes PROTO :LPVOID,:DWORD
;###############################################################################################
.DATA
noteC3 dd 7f3090h ;two octave scale C to C
instr01 dd 1C0h
noteD3 dd 7f3290h
instr02 dd 2C0h
noteE3 dd 7f3490h
instr03 dd 3C0h
noteF3 dd 7f3590h
instr04 dd 4C0h
noteG3 dd 7f3790h
instr05 dd 5C0h
noteA3 dd 7f3990h
instr06 dd 6C0h
noteB3 dd 7f3b90h
instr07 dd 7C0h
noteC4 dd 7f3c90h
instr08 dd 8C0h
noteD4 dd 7f3e90h
instr09 dd 9C0h
noteE4 dd 7f4090h
instr10 dd 0AC0h
noteF4 dd 7f4190h
instr11 dd 0BC0h
noteG4 dd 7f4390h
instr12 dd 0CC0h
noteA4 dd 7f4590h
instr13 dd 0DC0h
noteB4 dd 7f4790h
instr14 dd 0EC0h
noteC5 dd 7f4890h
termin dd 0 ;terminate list with a 0
;***********************************************************************************************
; .DATA?
;###############################################################################################
.CODE
;***********************************************************************************************
_main PROC
INVOKE PlayNotes,offset noteC3,550
INVOKE ExitProcess,0
_main ENDP
;***********************************************************************************************
PlayNotes PROC lpNoteList:LPVOID,dwDuration:DWORD
;--------------------------------------------------
LOCAL hMidiOut :HANDLE
;--------------------------------------------------
INVOKE midiOutOpen,addr hMidiOut,MIDI_MAPPER,NULL,0,CALLBACK_NULL
cmp eax,MMSYSERR_NOERROR
jnz PlayN2
push esi
push ebx
mov esi,lpNoteList
jmp short PlayN1
PlayN0: mov ebx,eax
INVOKE midiOutShortMsg,hMidiOut,eax
mov al,bl
and al,0F0h
and bl,0Fh
cmp al,90h ;is it "note on" ?
jnz PlayN1 ;no - next msg
or bl,80h ;yes - set "note off"
INVOKE Sleep,dwDuration ;after wait period
INVOKE midiOutShortMsg,hMidiOut,ebx
PlayN1: lodsd
or eax,eax
jnz PlayN0
INVOKE midiOutClose,hMidiOut
pop ebx
pop esi
PlayN2: ret
PlayNotes ENDP
;###############################################################################################
END _main