WaveQueue — Real-Time Sound Mixing Library for Windows (c)1994 Red Herring Transcribed 2026 from WAVEQ.DOC, the original Word 2.0 file, recovered off a Red Herring floppy. Text as written in August 1994; the line breaks and the tab-aligned argument tables are the only things that moved. ------------------------------------------------------------------------ WaveQueue Real-Time Sound Mixing Library for Windows ©1994 Red Herring What is WaveQueue? WaveQueue is a Windows library (DLL) that allows multiple sounds (currently up to four), or wave resources, to be mixed in real-time. WaveQueue is analogous to an audio mixer in that it takes a group of individual signals and overlays them together to form a single signal. WaveQueue acts as a singular wave output device that can be opened, closed, and flushed while allowing desired wave resources to be added or killed. Introduction A little over a year ago we set out to write an action game for Windows that would set a new standard for Windows entertainment based on solid gameplay, nice animation, and quality sound effects. After writing all of our own animation routines from scratch we were eager to add sampled sound effects and finish the game. What we found out after a few weeks of searching was that the standard Windows Multimedia Extensions did not support any methods of mixing digitized wave sounds and furthermore there wasn't any third party support either. This left us with two options: forget about sound effects or write our own mixer routines. We decided on the latter and they became WaveQueue. Incidentally, the game is called Combat Tanks and is an excellent demonstration of WaveQueue's capabilities. Supported Sound Types The current shareware version of WaveQueue, as well as the one shipped with Combat Tanks v1.0, supports only 8 bit, mono wave sounds sampled at 22kHz. This is a limitation we arrived at while testing different sound types and striking a balance between efficiency and sound quality. However, we are working at expanding the available types for a commercial version of WaveQueue. Library Functions Following is a list of all of the functions that comprise the WaveQueue sound library, as found in the header file WAVEQ.H. Although there are eleven functions in all, some are support functions for others, leaving you with only a handful to call in your own applications. BOOL FAR PASCAL WQ_OpenDevice(void); BOOL FAR PASCAL WQ_CloseDevice(void); BOOL FAR PASCAL WQ_Add(LPSTR,DWORD,BOOL=FALSE); void FAR PASCAL WQ_Kill(LPSTR); void FAR PASCAL WQ_Flush(void); BOOL FAR PASCAL WQ_IsWaveSupported(void); BOOL FAR PASCAL WQ_GetWaveData(HINSTANCE,LPCSTR,LPSTR FAR *,DWORD FAR *); DWORD FAR PASCAL WQ_SizeofWave(HINSTANCE,LPCSTR); HGLOBAL FAR PASCAL WQ_LoadWave(HINSTANCE,LPCSTR); HANDLE FAR PASCAL WQ_PlayWave(HINSTANCE,LPCSTR); Function Descriptions In this section each function is listed along with a formal description of its arguments and use. There is a Windows SDK style C example application provided with this release of WaveQueue that is a good starting point after reading the function descriptions. BOOL FAR PASCAL WQ_OpenDevice(void); This function opens and initializes the queue and must be called before any sounds can be added to the queue. It returns TRUE on success and FALSE on failure. This function is always paired with the complementary WQ_CloseDevice() function in that the queue should be closed anytime the application goes inactive, as well as when it terminates. For example, there will usually be a call to WQ_OpenDevice() in a WM_SETFOCUS handler and a corresponding call to WQ_CloseDevice() in the WM_KILLFOCUS handler. BOOL FAR PASCAL WQ_CloseDevice(void); This function closes the WaveQueue. It returns TRUE on success and FALSE on failure. See previous description of WQ_OpenDevice() for more information on its usage. BOOL FAR PASCAL WQ_Add(LPSTR lpWaveData,DWORD dwWaveDataSize,BOOL bRepeat=FALSE); LPSTR lpWaveData pointer to wave data DWORD dwWaveDataSize size of wave data BOOL bRepeat repetitive wave? This function adds a wave resource to the queue for playing. It returns TRUE on success and FALSE on failure. Once added, a wave will be played once the next available slot, or channel, in the queue becomes available. This implementation of WaveQueue supports four active channels and four pending channels, meaning that while four waves are playing together, four more can be queued for play as soon as the current ones finish. The mechanism for queueing and playing waves is all handled internally. All you must do is add the wave to the queue. When TRUE, the bRepeat parameter causes the wave to repeat, or loop, until it is explicitly killed. An example of this usage is the chopper sound in Combat Tanks, which is really a short sound repeated over and over. void FAR PASCAL WQ_Kill(LPSTR lpWaveData); LPSTR lpWaveData pointer to wave data This function kills a wave resource from the queue. This is the primary means of getting rid of repetitive waves since they will persist until the WaveQueue device is closed. void FAR PASCAL WQ_Flush(void); This function flushes the queue killing all playing waves and removing all pending waves. BOOL FAR PASCAL WQ_IsWaveSupported(void); This function returns TRUE if the default wave type is supported and FALSE if it is not. For this version of WaveQueue, the default wave type is 8 bit mono sampled at 22kHz. Use this function on initialization to determine whether or not WaveQueue sounds can be supported on the system. BOOL __export FAR PASCAL WQ_GetWaveData(HINSTANCE hinst, LPCSTR szResName,LPSTR FAR *lpWave,DWORD FAR *dwWaveSize) HINSTANCE hinst module instance handle (location of wave resources) LPCSTR szResName name of wave resource (in RC file) LPSTR FAR * lpWave pointer to wave data DWORD FAR * dwWaveSize size of wave data This function gets the binary wave data associated with the wave resource. You must provide the instance handle and resource name as well as pointers to receive the data and size of the data. Please note that waves are not standard resources like bitmaps or icons. However, WaveQueue is setup to use wave resources as user-defined type WAVE. So, when defining a wave resource in your RC file, use the word WAVE as you would normally use BITMAP or ICON. The example application uses demonstrates this. void __export FAR PASCAL WQ_FreeWaveData(LPSTR FAR *lpWave) LPSTR FAR * lpWave pointer to wave data This function frees the binary wave data associated with the wave resource. You must provide the pointer that was used to receive the data via WQ_GetWaveData. DWORD FAR PASCAL WQ_SizeofWave(HINSTANCE,LPCSTR); HINSTANCE hinst module instance handle (location of wave resources) LPCSTR szResName name of wave resource (in RC file) This function returns the size of the binary wave data associated with the wave resource. You must provide the instance handle and resource name. HGLOBAL FAR PASCAL WQ_LoadWave(HINSTANCE,LPCSTR); HINSTANCE hinst module instance handle (location of wave resources) LPCSTR szResName name of wave resource (in RC file) This function returns a handle to the wave resource. You must provide the instance handle and resource name. This function is usually not called explicitly as it is called internally by WQ_GetWaveData and WQ_PlayWave, but it is provided for consistency should a wave handle be needed. HANDLE FAR PASCAL WQ_PlayWave(HINSTANCE,LPCSTR); HINSTANCE hinst module instance handle (location of wave resources) LPCSTR szResName name of wave resource (in RC file) This function is the only one in WaveQueue that is not related to mixing waves. It allows waves to be played singularly from memory. It serves as a sndPlaySound for WAVE resource types allowing you to build waves into the resource file and play them directly from memory, which is much more efficient than passing a filename and opening a file from disk. It returns a handle to the wave resource. You must provide the instance handle and resource name.