Generating musical Tones.

The system I am working on has about 3 million bytes tied up in .WAV files.
What I would rather do is generate the TONE on the fly by entering the
Frequency, Duration and Volume. There would be no .WAV files and the
package would be much smaller. I don't think it would have any impact on
the speed of the application. I will only be writing this one application
involving sound so I would rather not get into the nitty-gritty of Riff code
or whatever they call the sound programs. I also want the screen left
alone, no message boxes or midi windows, just the sound to be generated.
I know this can be done at a much lower level but the sound is awful.

Thanks for any help...
Posted on 2003-07-23 08:06:42 by shankle
Sound a bit like MIDI to me. ("just" replace the instruments with tone scales)
Posted on 2003-07-23 09:38:34 by scientica
Kernel32 has this api:

BOOL Beep(

DWORD dwFreq, // sound frequency, in hertz
DWORD dwDuration // sound duration, in milliseconds
);
Posted on 2003-07-23 10:42:40 by david
Hi,

Yes, Midi is a good way to generate simple tones or chords based around the midiOutShortMsg API. Longer passages can be created using timers or sending raw midi data with System Exclusive messages and the midiOutLongMsg function. There's lots of information at a good midi programming site such as

http://www.borg.com/~jglatt/

Just a brief description, a simple MIDI message as sent by midiOutShortMsg is defined by 3 bytes or less, and is made up of an eight-bit Status byte (packed into the lowest order byte of a dword value), and generally followed by one or two Data bytes. To play a note you use the 'Note On' midi message, and there are several others to control things like pitch, volume or Program (instrument) change.

Middle C is defined by the system as equ 60, 1 octave below Middle C equ 48, 1 octave above equ 72. The Note On message is constructed like this

; Note On Event 9n kk vv
;db 90h ; n = channel 0-16 - 90h selects Channel 0
;db 3Ch ; kk = key/note number 0-127 - Output the C note (Middle C = 60 = 3Ch)
;db 7Fh ; vv = velocity 0-127 - essentially attack volume (0 is silence)

And the message can be sent with a simple piece of code:

;===========================


;.data

; Define a C chord using Note On events
; Output notes at maximum volume (7Fh) on channel 0 (90h)
; (Middle C = 60 = 3Ch)
RIFF1 dd 007F3C90h ; Output the C note
dd 007F4090h ; Output the E note
dd 007F4390h ; Output the G note

;.code

push MIDI_MAPPER
pop [uDeviceID]
; You can select any midi device on your system to use certain
; extended capabilities, though the MIDI_MAPPER eventually
; processes all MIDI messages anyway.

invoke midiOutOpen, offset lphmo, [uDeviceID],\
offset MidiOut_Callback, 0, CALLBACK_FUNCTION

invoke midiOutShortMsg, lphmo, dword ptr [RIFF1+0] ; C note
invoke midiOutShortMsg, lphmo, dword ptr [RIFF1+4] ; E note
invoke midiOutShortMsg, lphmo, dword ptr [RIFF1+8] ; G note

invoke Sleep, 1000 ; delay so you can hear the notes sounding
invoke midiOutReset, lphmo
invoke midiOutClose, lphmo


You mention your wav files are 'tones' so something like this might be suitable using a high res timer to control how they sound. Good luck.

Kayaker
Posted on 2003-07-23 19:07:54 by Kayaker