|
Sound & Games
The Next Level
The WAVEMIX32.DLL
The methods used so far, though
easy, are of limited use to us simply because we cannot play
simultaneous sound files. Some time ago Microsoft developed an
in-house set of dlls, which wrapped around the low-level wave API
and enabled up to 8 channels of sound simultaneously. They were
soon released free to the public as one of Microsofts
unsupported tools. We can use one of these dlls, the
WAVEMIX32.DLL (the other is the WAVEMIX16.DLL) to accomplish what
we want. Though the use of this dll to playback wave files is a
bit more complicated than what we have used so far, it does add
the extra dimension of reality when you can have more than one
sound played at any given time.
Overview of the WAVEMIX API
The WaveMix32 functions allow us
to play sounds from 8 channels at a time. But this is not
accomplished as easy as what we experienced with the Win32 option
for playing sound. There are certain steps, which we must take in
order to use the dll.
Before anything else we have to
initialize the DLL. After this initialization we can deal with
the opening of the wave files and playing them using the dll.
After everything has finished and we do not want to use the dll
anymore we have to free the resources we have acquired through
the dll. Put into perspective then these are the steps, which we
must take:
- Initialize the dll
- Open and play the sounds
- Free any used resources
This seems very simple and
straightforward, but there is a bit more to it than that.
Lets take a closer look at the function, which we must use
to do theses steps.
Step 1:
The WaveMix32 dll can be
initialized via two functions; WaveMixInit() and WaveMixConfigureInit.
These are declared as such:
Declare Function WaveMixInit Lib "WAVMIX32.DLL" () As Long
Declare Function WaveMixConfigureInit Lib "WAVMIX32.DLL" (NewConfig As MIXCONFIG) As Long
|
The WaveMixInt() function
will configure the DLL using the default settings and the
settings specified in the wavemix.ini file.
The WaveMixConfigureInit()
function will configure the DLL according to the settings
specified in the lpConfig parameter. The lpConfig
parameter is a structure defined as such:
Type MIXCONFIG
Size As Integer
Flags As Long
Channels As Integer
SamplingRate As Integer
End Type
Description:
Size: The size of the type. Use Len(MIXCONFIGTYPE) to set this parameter.
Flags: The bitwise OR flags which determines the settings which should be set
Channels: The number of output channels to use. 1 = MONO, 2 = STEREO. You must set the
WMIX_CONFIG_CHANNELS constant in the Flags member of this type with the bitwise OR
operator.
SamplingRate: The output sampling rate you wish to use. 11 = 11.025 kHz, 22 = 22.050 kHz,
44 = 44.1 kHz. You must set the WMIX_CONFIG_SAMPLINGRATE constant in the Flags
member of this type with the OR operator.
|
Both of these functions will
return a handle (long value) to the session you create. This
handle will be used throughout the calls to the WavMix32 API, so
save it. If for some reason one of the funcitons fails, 0 will be
returned.
NOTE: Only use one of
these initializing function for each session.
Step 2:
After initializing the dll, we
can now begin to load the wave files we need. The function for
loading wave files is the WaveMixOpenWave():
Declare Function WaveMixOpenWave Lib "WAVMIX32.DLL" _
(ByVal MixSession As Long, _
WaveFilename As Any, _
ByVal hInst As Long, _
ByVal Flags As Long) As Long
Parameters:
MixSession: The session handle returned by either of the initializing functions.
WaveFileName: This parameter could one of many different things, depending on the flags set
in the Flags parameter. The possible variations: File name to a wave file or a name of a WAVE
resource to open or an ID (integer) of a WAVE resource to open.
hInst: The instance of the module, which contains the resource.
Flags:
WMIX_FILE: The WaveFileName parameter is a file name of the WAVE file. The
file name must not be longer than 127 characters. Do not set this flag with the
WMIX_RESSOURCE flag. The hInst parameter is ignored and can be set to 0.
WMIX_RESSOURCE: The WaveFileName specifies a resource to be opened in the
hInst module.
|
The return value from the
function is an identifier for the loaded wave file, which will be
used when the file is to be played. If the function failed to
open the specified wave file it will return 0.
After successfully opening a
wave file we a channel to play it in. To open a channel we use
the WaveMixOpenChannel() function:
Declare Function WaveMixOpenChannel Lib "WAVMIX32.DLL" _
(ByVal MixSession As Long, _
ByVal Channel As Long, _
ByVal Flags As Long) As Long
Parameters:
MixSession: The session handle returned from the initializing functions.
Channel: The Channel you wish to open. It can be from Channel 0 to Channel 7 both included.
There is no particular in which you have to open or close the channels.
Flags: The following flags are available:
WMIX_OPENSINGLE: The Channel parameter specifies the single channel to be
opened.
WMIX_ALL: All the available channels will be opened.
WMIX_OPENCOUNT: The Channel parameter specifies the number of channels to
be opened. If Channel = 3 then channels 0 through 2 will be opened.
The function returns 0 on success.
|
The next thing to do is to
activate the channels, so the dll will acquire the WAVE output
device. This is done by a call to the WaveMixActivate() function:
Declare Function WaveMixActivate Lib "WAVMIX32.DLL" _
(ByVal MixSession As Long, ByVal Activate As Integer) As Long
Parameters:
MixSession: The session handle returned by one of the two initializing functions
Activate: If 0 is passed the channels will become inactive. If 1 is passed the channels will
become active. You should call this function with 0 in the Activate parameter, when your
application loses focus. This will enable other running applications to play wave sounds from
the wave device.
The function will return 0 on success, and non-zero on failure.
|
Now we have an open WAVE file
from the WaveMixOpenWave() function and a open channel
from the WaveMixOpenChannel(), which has been activated
with the WaveMixActivate() function. It is time to play
some waves.
The wave files are played with a
call to the WaveMixPlay() function:
Declare Function WaveMixPlay Lib "WAVMIX32.DLL" (PlayParameters As MIXPLAYPARAMS) As Integer
Parameters:
PlayParameters: This parameter is a Type structure which sets the different play settings for
the wave. The type structure is declared as such:
Public Type MIXPLAYPARAMS
Size As Integer
MixSessionLo As Integer
MixSessionHi As Integer
ChannelLo As Integer
ChannelHi As Integer
MixWaveLo As Integer
MixWaveHi As Integer
hWndNotifyLo As Integer
hWndNotifyHi As Integer
FlagsLo As Integer
FlagsHi As Integer
wLoops As Integer
End Type
Size: The size of the structure. Use the Visual Basic Len() function to set this parameter.
MixSessionLo: The lower WORD of the session handle returned by the initializing functions. Use
the LowerWord() (declared in WAVEMIX32.bas module) to get the lower word of the session
handle.
MixSessionHi: The high WORD of the session handle returned by one of the initializing
functions. Use the HighWord() (declared in the WAVEMIX32.bas module) function to get the
High Word of the session handle.
ChannelLo: The lower word of the channel on which the wave should be played. The channel
must be active.
ChannelHi: The high word of the channel, on which the sound should be played. The channel
must be active.
MixWaveLo: The lower word of a wave handle, opened with the WaveMixOpenWave() function.
MixWaveHi: The high word of a wave handle, opened with the WaveMixOpenWave() function.
hWndNotifyLo: The lower word of a window handle to a window which will receive a
MM_WOM_DONE message when the playback of the wave has finished. If this is parameter is
set to 0, the message will not be posted.
hWndNotifyHi: The high word of a window handle to a window which will receive a
MM_WOM_DONE message when the playback of the wave has finished. If this is parameter is
set to 0, the message will not be posted.
FlagsLo: The lower word of a set of flags combined with the OR operator. The flags available
are:
WMIX_QUEUEWAVE: The wave will be put into the queue of waves currently in
the channel. The wave are played in the order of first in first played.
WMIX_CLEARQUEUE: The wave will preempt all waves currently in the channel.
This message should be combined the WMIX_QUEUEWAVE flag.
WMIX_HIGHPRIORITY: The wave will be played immediately. If the flag is not set,
the will be a slight delay before the wave is played. This will flag will set the wave
in front of the queue if the flag is combined with the WMIX_QUEUEWAVE flag.
WMIX_USELRUCHANNEL: The wave should be played on the first available
channel or played on the most recently used channel. This flag should be
combined with either the WMIX_QUEUEWAVE or the WMIX_CLEARQUEUE flags,
but not both.
FlagsHi: The high word of a set of flags combined with the OR operator. The flags are the same
as with the FlagsLo parameter
Loops: The number of times the wave should be repeated. If this flag is set to &hFFFF the
wave will loop until the channel is closed, flushed or preempted.
The function will return 0 on success, and non-zero on failure.
|
To stop a sound from playing or
to empty a channel you use the WaveMixFlushChannel() function:
Declare Function WaveMixFlushChannel Lib "WAVMIX32.DLL" _
(ByVal MixSession As Long, ByVal Channel As Long, ByVal Flags As Long) As Integer
Parameters:
MixSession: The session handle returned by one of the initializing functions.
Channel: the channel to be flushed
Flags:
WMIX_ALL: Causes all channels to be flushed.
WMIX_NOREMIX: Prevents the function from causing the data in the wave device
to be immediately remixed.
The function returns 0 if it was successful.
|
Step 3:
When ending an application that
has used the WaveMix32 you must free the resources that the dll
used. This is done in three steps. The first step is to close the
opened channels. This is done with the WaveMixCloseChannel()
function:
Declare Function WaveMixCloseChannel Lib "WAVMIX32.DLL" _
(ByVal MixSession As Long, ByVal Channel As Long, ByVal Flags As Long) As Integer
Parameters:
MixSession: The session handle returned from the initializing functions.
Channel: The channel to be closed. It must have been previously opened with the
WaveMixOpenChannel() function.
Flags:
WMIX_ALL: Causes all channels to be closed
The function returns 0 on success.
|
After closing all the channels
you must free the wave resources used. This is done with the WaveMixFreeWave()
function:
| Declare Function
WaveMixFreeWave Lib "WAVMIX32.DLL" _ (ByVal MixSession As Long,
ByVal MixWave As Long) As Integer
Parameters:
MixSession:
The session handle returned by one of the initializing
functions.
MixWave:
A handle of the wave file to be freed. This must be a
valid return value form the WaveMixOpenFile()
functions.
The function returns
0 on success.
|
This function must be called on
all the wave resources used in the session, which should be
ended.
The final thing to clean up is
the actual session. This is done via a call to the WaveMixCloseSession()
function:
Declare Function WaveMixCloseSession Lib "WAVMIX32.DLL" _
(ByVal MixSession As Long) As Integer
Parameters:
MixSession: The session handle, which was returned from either of the initializing functions.
You must call this function before ending the application, which uses the WaveMix32 DLL, in
order to free the acquired system resources.
The function returns 0 if it was successful.
|
The sample project WAVMIX
demonstrates the use of the WaveMix32.dll to playback multiple
sounds simultaneously.
The project is quite simple,
since it only playbacks the four sounds, which each have a unique
assigned channel. There are more possibilities and functions in
the WaveMix32.dll than those listed here and if you are
interested you may want to search Microsoft and see what you can
find.
[Sound & Games #1] [Sound & Games #2] [Sound & Games #3] [Download All Samples]
These tutorials were originally developed by
Soren Christensen and Burt Abreu as part of a book which we were working on.
The book idea didn't come to fruition and so we decided to post the completed
chapters here in the hopes that you would find them useful. We retain copyright
to this material and you may not reproduce it, post it, or otherwise disseminate
it in any fashion without our express written consent with the exception of making
copies for your personal use.
|