5-19-2013
; Been a long time since I wrote this system and can't for the life of me
; remember how I arrived at the noteC3 thingie.
; Same for the Playnotes.
; This uses the Midi Disaster.
; When I wrote this system in Windows 98-32-bit, the sound worked just
; fine. It also worked in Vista 32-bit.
; It also works in Windows 7 32-bit using Masm32 on my HP Pavilion 64-bit
; puter.
; The sound doesn't work very well in my converted to GoAsm 32-bit
; version on the 64-bit Pavilion or on a Windows 7 32-bit puter.
; I created a 64-bit version of the GoAsm program and no sound emerges
; from it.
; Found two headers in Donkeys headers with Midi referenced in them -
; mmreg.h and mmsystem.h. I have no idea if they are included in my
; program at link time or if they work on my setup.
; In the (noteC3) definition I have no idea how I got the "7f" or the "90".
; The 3rd byte is the pitch of the note. Like "30" represents the note
; "C" 3rd octave.
lphmo dq 0
; two octave scale C to C.
noteC3 dd 007f3090h
noteD3 dd 007f3290h
noteE3 dd 007f3490h
noteF3 dd 007f3590h
noteG3 dd 007f3790h
noteA3 dd 007f3990h
noteB3 dd 007f3b90h
noteC4 dd 007f3c90h
noteD4 dd 007f3e90h
noteE4 dd 007f4090h
noteF4 dd 007f4190h
noteG4 dd 007f4390h
noteA4 dd 007f4590h
noteB4 dd 007f4790h
noteC5 dd 007f4890h
duration dd 00000226h
tc dd 0
noteX dd 0
lea eax,[noteC3] etc.
mov [noteX],eax
invoke PlayNotes, [noteX] ;Play C3
; other code
PlayNotes:
FRAME noteX
invoke midiOutOpen, offset lphmo, -1, NULL, 0, CALLBACK_NULL
; ecx points to notes
; edx points to the duration of the note
mov ecx,[noteX]
lea edx,duration ; duration of note
push ecx
push edx
invoke midiOutShortMsg, [lphmo],[ecx] ; varying notes
pop edx
pop ecx
push ecx
push edx
invoke GetTickCount ; get a time reference
pop edx
pop ecx
mov [tc],eax
mov eax,[edx]
add [tc],eax
.TimeCount
push ecx
push edx
invoke GetTickCount
pop edx
pop ecx
cmp [tc],eax
jg <.TimeCount
invoke midiOutReset, [lphmo]
invoke midiOutClose, [lphmo]
ret
ENDF
Hope somebody has some ideas on this subject.
Quote from: shankle on May 20, 2013, 01:51:51 AM
Hope somebody has some ideas on this subject.
Try to simplify your proggie.
Here's a sample ( Masm ) that plays 3 chords - it works:
.386
.Model flat, stdcall
option casemap:none
WIN32_LEAN_AND_MEAN equ 1
.nolist
.nocref
include windows.inc
include mmsystem.inc
.list
.cref
CStr macro text:vararg
local xxx
.const
xxx db text,0
.code
exitm <offset xxx>
endm
.data
g_hConOut dd 0
.code
;--- printf emulation
printf proc c pszText:dword, parms:VARARG
local dwWritten:dword
local szText[128]:byte
invoke wvsprintf, addr szText, pszText, addr parms
lea ecx, dwWritten
invoke WriteConsole, g_hConOut, addr szText, eax, ecx, 0
ret
printf endp
main proc c
local hMidiOut:HANDLE
invoke GetStdHandle, STD_OUTPUT_HANDLE
mov g_hConOut, eax
invoke midiOutGetNumDevs
.if (!eax)
invoke printf, CStr(<"midiOutGetNumDevs() returned 0",10>)
jmp @exit
.endif
Invoke midiOutOpen, addr hMidiOut, MIDI_MAPPER, NULL, NULL, CALLBACK_NULL
push eax
.if (eax != MMSYSERR_NOERROR)
invoke printf, CStr(<"midiOutOpen() failed [%u]",10>), eax
.else
invoke printf, CStr(<"midiOutOpen() ok",10>)
.endif
pop eax
.if (eax != MMSYSERR_NOERROR)
jmp @exit
.endif
; int 3
Invoke midiOutShortMsg, hMidiOut, 7F3C90h
Invoke midiOutShortMsg, hMidiOut, 7F4090h
Invoke midiOutShortMsg, hMidiOut, 7F4390h
invoke Sleep, 200
Invoke midiOutShortMsg, hMidiOut, 003C90h
Invoke midiOutShortMsg, hMidiOut, 004090h
Invoke midiOutShortMsg, hMidiOut, 004390h
invoke Sleep, 20
Invoke midiOutShortMsg, hMidiOut, 7F4190h
Invoke midiOutShortMsg, hMidiOut, 7F4590h
Invoke midiOutShortMsg, hMidiOut, 7F4890h
invoke Sleep, 200
Invoke midiOutShortMsg, hMidiOut, 004190h
Invoke midiOutShortMsg, hMidiOut, 004590h
Invoke midiOutShortMsg, hMidiOut, 004890h
invoke Sleep, 20
Invoke midiOutShortMsg, hMidiOut, 7F4390h
Invoke midiOutShortMsg, hMidiOut, 7F4790h
Invoke midiOutShortMsg, hMidiOut, 7F4A90h
invoke Sleep, 500
Invoke midiOutShortMsg, hMidiOut, 004390h
Invoke midiOutShortMsg, hMidiOut, 004790h
Invoke midiOutShortMsg, hMidiOut, 004A90h
invoke midiOutClose, hMidiOut
invoke printf, CStr(<"midiOutClose()=%X",10>), eax
@exit:
ret
main endp
start:
invoke main
invoke ExitProcess, 0
end start
also - be sure to check your midi device volume
i don't know how many times i have found it set to 0 :P
hiya Jack
as you know, i am not much of a GoAsm guy :P
but, this seems to work ok using MASM Syntax
;###############################################################################################
.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
noteD3 dd 7f3290h
noteE3 dd 7f3490h
noteF3 dd 7f3590h
noteG3 dd 7f3790h
noteA3 dd 7f3990h
noteB3 dd 7f3b90h
noteC4 dd 7f3c90h
noteD4 dd 7f3e90h
noteE4 dd 7f4090h
noteF4 dd 7f4190h
noteG4 dd 7f4390h
noteA4 dd 7f4590h
noteB4 dd 7f4790h
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
mov esi,lpNoteList
jmp short PlayN1
PlayN0: INVOKE midiOutShortMsg,hMidiOut,eax
INVOKE Sleep,dwDuration
INVOKE midiOutReset,hMidiOut
PlayN1: lodsd
or eax,eax
jnz PlayN0
INVOKE midiOutClose,hMidiOut
pop esi
PlayN2: ret
PlayNotes ENDP
;###############################################################################################
END _main
Thanks Guys for responding.
The system has been working in MASM32 for years.
Here are the files included in the MASM32 relevant program.
Something is either missing in the GoAsm files or it's something to
do with the 64-bit HP puter or both.
I'm still to green in GoAsm to know where to start looking for the problem.
include \masm32\include\windows.inc
(many equates referring to MIDI in here)
include \masm32\include\gdi32.inc - nothing here
include \masm32\include\user32.inc - nothing here
include \masm32\include\kernel32.inc - nothing here
include \masm32\include\winmm.inc
(Many references in here - some are proto statements)
i am with Japheth
simplify your code
no need for all those pointers to pointers :P
you include winmm.inc, you may also need to includelib winmm.lib
(not sure how GoAsm works, in that respect)
The "9nh" is the MIDI status byte for Note On on channel n (0-F). You have the Note Number right. The next byte "vvh" is the attack velocity (01-7F, with 00 another way for Note Off).
You use ecx as a pointer to the note, so in the call to midiOutShortMsg you should use [ecx]. That should fix things on the 32-bit side.
If you are using Donkey's headers, then mmsystem.h will be included (from windows.h as long as you have not defined WIN_LEAN_AND_MEAN), and this then also adds instructions for the linker to include winmm.dll (if you have defined LINKFILES, otherwise you need to add this dll to the GoLink command line).
Thank you WJR for responding.
The 1st two paragraphs I think I understand.
I am using Donkey's headers.
I have no idea what "WIN_LEAN_AND _MEAN" is.
Am I correct in saying that this will not solve the 64-bit
problem? Or are the Headers the same for both?
I have two of these, one for 32bits and one for 64bits.
Is this what you mean?
#define LINKFILES
#define codejps
#define WIN64
#INCLUDE windows.h
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
Thanks much WJR.
The 32-bit program is now working.
The 64-bit program is also working.
All caused by [ecx].
I've got a long way to go with GoAsm.....
The program in this thread is now working Dave,
so you have what you asked for.
yes :t
i would like to figure out which instrument to use to get a straight beep tone
it would be nice if i could use this method for morse code
Hi Dave,
I would like the Congo drums used in the old Tarzan movies.... :biggrin:
Piano
1 Acoustic Grand Piano
2 Bright Acoustic Piano
3 Electric Grand Piano
4 Honky-tonk Piano
5 Electric Piano 1
6 Electric Piano 2
7 Harpsichord
8 Clavinet
Chromatic Percussion
9 Celesta
10 Glockenspiel
11 Music Box
12 Vibraphone
13 Marimba
14 Xylophone
15 Tubular Bells
16 Dulcimer
Organ
17 Drawbar Organ
18 Percussive Organ
19 Rock Organ
20 Church Organ
21 Reed Organ
22 Accordion
23 Harmonica
24 Tango Accordion
Guitar
25 Acoustic Guitar (nylon)
26 Acoustic Guitar (steel)
27 Electric Guitar (jazz)
28 Electric Guitar (clean)
29 Electric Guitar (muted)
30 Overdriven Guitar
31 Distortion Guitar
32 Guitar Harmonics
Bass
33 Acoustic Bass
34 Electric Bass (finger)
35 Electric Bass (pick)
36 Fretless Bass
37 Slap Bass 1
38 Slap Bass 2
39 Synth Bass 1
40 Synth Bass 2
Strings
41 Violin
42 Viola
43 Cello
44 Contrabass
45 Tremolo Strings
46 Pizzicato Strings
47 Orchestral Harp
48 Timpani
Ensemble
49 String Ensemble 1
50 String Ensemble 2
51 Synth Strings 1
52 Synth Strings 2
53 Choir Aahs
54 Voice Oohs
55 Synth Choir
56 Orchestra Hit
Brass
57 Trumpet
58 Trombone
59 Tuba
60 Muted Trumpet
61 French Horn
62 Brass Section
63 Synth Brass 1
64 Synth Brass 2
Reed
65 Soprano Sax
66 Alto Sax
67 Tenor Sax
68 Baritone Sax
69 Oboe
70 English Horn
71 Bassoon
72 Clarinet
Pipe
73 Piccolo
74 Flute
75 Recorder
76 Pan Flute
77 Blown Bottle
78 Shakuhachi
79 Whistle
80 Ocarina
Synth Lead
81 Lead 1 (square)
82 Lead 2 (sawtooth)
83 Lead 3 (calliope)
84 Lead 4 (chiff)
85 Lead 5 (charang)
86 Lead 6 (voice)
87 Lead 7 (fifths)
88 Lead 8 (bass + lead)
Synth Pad
89 Pad 1 (new age)
90 Pad 2 (warm)
91 Pad 3 (polysynth)
92 Pad 4 (choir)
93 Pad 5 (bowed)
94 Pad 6 (metallic)
95 Pad 7 (halo)
96 Pad 8 (sweep)
Synth Effects
97 FX 1 (rain)
98 FX 2 (soundtrack)
99 FX 3 (crystal)
100 FX 4 (atmosphere)
101 FX 5 (brightness)
102 FX 6 (goblins)
103 FX 7 (echoes)
104 FX 8 (sci-fi)
Ethnic
105 Sitar
106 Banjo
107 Shamisen
108 Koto
109 Kalimba
110 Bagpipe
111 Fiddle
112 Shanai
Percussive
113 Tinkle Bell
114 Agogo
115 Steel Drums
116 Woodblock
117 Taiko Drum
118 Melodic Tom
119 Synth Drum
Sound effects
120 Reverse Cymbal
121 Guitar Fret Noise
122 Breath Noise
123 Seashore
124 Bird Tweet
125 Telephone Ring
126 Helicopter
127 Applause
128 Gunshot
let's try the Taiko Drums :biggrin: