SEAL Synthetic Audio Library 1.07
Programmer's Guide
Copyright Information
Information in this document is subject to change without notice. No part of this document may be reproduced or transmitted in any form or by any means, electronic or mechanical, for any purpose, without the express written permission of the author.
The Synthetic Audio Library Software Developer Kit
Copyright (C) 1995-1999 Carlos Hasan
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
If you have questions, problems or comments about the SEAL audio system you can contact the author at the following Internet email address:
Carlos Hasan
chasan@dcc.uchile.cl
About the Synthetic Audio Library
The Synthetic Audio Library application programming interface allows your applications to play digital audio waveforms and multichannel music sequences in your applications, provides low-latency mixing, hardware acceleration and dynamic digital filtering for improved sound quality.
The SEAL API allows you, as an application developer, access the audio hardware while insulating you from the specific details of that hardware. The design goal of SEAL is speed. Instead of providing a high-level set of functions, it provides a device-independant interface, allowing applications to take full adventage of the capabilities of the audio hardware.
Supported Platforms and Hardware
The Synthetic Audio Library SEAL SDK is available for DOS, Extended DOS, Windows 95, Windows NT and Linux operating systems. The following compilers are supported in the current version of the audio system:
- WATCOM C/C++32 10.0 Compiler for DOS4GW and Win32
- DJGPP 2.0 Compiler port of GNU CC for DOS/DPMI32
- GNU CC 2.7.0 Compiler for Linux (a.out and ELF) operating system
- Visual C++ 4.1 Compiler for Windows 95 and Windows NT
- Borland Delphi 2.0 Compiler for Windows 95 and Windows NT
- Metrowerks CodeWarrior C++ for BeOS Intel Release 3
- GNU CC Compiler for BeOS Intel Release 4
- EMX port of GNU CC 2.7.x Compiler for OS/2 operating system
Any other language for Windows 95 or Windows NT with 32-bit dynamic link libraries support, such as Visual Basic or Borland C++ 5.0, should also be able to use the audio system AUDIOW32.DLL dynamic link library.
Under the DOS operating system the following hardware audio devices are natively supported by the audio system:
- Sound Blaster 1.0
- Sound Blaster 1.5
- Sound Blaster 2.0
- Sound Blaster Pro I and II
- Sound Blaster 16 / ASP
- Sound Blaster 32
- Sound Blaster AWE32
- Creative PCI64 and PCI128 cards
- Windows Sound System
- Ensoniq Soundscape
- Ensoniq Soundscape Elite
- Ensoniq AudioPCI cards
- Gravis Ultrasound
- Gravis Ultrasound Daughterboard
- Gravis Ultrasound MAX
- AMD InterWave-based boards
- Pro Audio Spectrum
- Pro Audio Spectrum Plus
- Pro Audio Spectrum 16
- Aria sound cards
Other sound devices compatible with any of the above sound boards are also supported.
Data Types
The most fundamental data types used in the audio system are waveforms, modules and voices. The waveform data type represent digital audio data of individual sources of sound, modules represent multichannel music sequences, and voices represent monophonic audio channels used to play waveforms. Each voice can control the sound characteristics of the waveform that is being played through it, such as frequency and volume levels.
Features
- Mixing
The most used feature of the audio system is the low-latency mixing of digital audio channels. Your application can create up to 32 voices to play concurrently audio data through your sound device. The audio system mixes all the active voices and writes the result to the audio hardware.
Low-latency mixing allows the user to experience no perceptible delay between the time that the application start playing a waveform through the audio hardware and the time that the speakers reproduct the sound.
- Hardware Acceleration
The SEAL audio system automatically takes advantage of accelerated sound hardware, including hardware mixing and hardware local memory. Your application does not need to query the hardware to specifically use hardware acceleration.
Audio Device Interface
Initialization
The audio device interface allows your application to communicate and control the audio hardware on the system. Your application must initialize the audio system to be able to start using it by calling the AInitialize routine. It's not required for Windows 95 and Windows NT applications.
Device Capabilities
Before initializing the audio device for playback, your application can enumerate and retrieve information of the registered audio device drivers. The device drivers are enumerated starting from zero, and the AGetAudioNumDevs routine returns the number of audio device drivers installed on the system. The application can retrieve the capabilities information of any of the installed audio device drivers by calling the routine AGetAudioDevCaps.
Your application can also call the routine APingAudio to determine what kind of audio hardware is present on the system. If there is more than one device present on the system, the first detected audio device will be used.
Opening the Audio Device
After investigating the capabilities of the sound device, your application can open the audio hardware for playback calling AOpenAudio and specifying what audio device, output format, and sampling frequency should be used. Since the specified audio device might not support the desired parameters, the audio system will use the closest configuration supported by the audio hardware.
While the audio system is active, your application must call the routine AUpdateAudio to update and send the output audio buffers to the audio hardware. It's not required for Windows 95 and Windows NT applications.
Closing the Audio Device
Applications can release the audio hardware by calling the ACloseAudio routine. It's very important to release all the allocated waveforms, modules and voice resources before closing the audio system.
Timer Interrupt Services
Your application can install a virtual audio timer interrupt callback routine by calling the ASetAudioTimerProc routine. The rate or speed at which the virtual audio timer routine is called can be changed by calling the routine ASetAudioTimerRate. Since the installed timer callback routine can be called from within a hardware interrupt handler, for applications running under the DOS operating system, your timer routine has the same constrains than hardware interrupt handler routines.
Since the audio system plays music sequences using the virtual audio timer interrupt services, your applications won't be able to play music modules and use the timer services simultaneously. You must use your own timer services if you want to play music in your applications. For applications running in DOS, the hardware timer interrupt vector can be used for such purposes.
Audio Voice Interface
Creating Audio Voices
Your application can allocate audio voices to play digital audio waveforms concurrently. After calling the routine AOpenVoices to specify the amount of available audio voices, your application can call the ACreateAudioVoice routine to allocate audio voices.
Every allocated audio voice must be released by calling ADestroyAudioVoice whenever your application finishes using it. It's important to stop the audio voices before releasing them.
The ACloseVoices routine must be called to release all the available audio voices when your application is going to close the audio system. Your application must stop all the voices and module files before calling it.
Play Management
Your application can start playing a waveform through a voice by calling the APlayVoice or APrimeVoice routines. The real-time playback of the audio voices is controlled by calling the AStartVoice and AStopVoice routines. The voice stops automatically when the end of the waveform is reached. However, if looping is specified, the voice repeats until AStopVoice is called.
To retrieve or set the current playing position in the waveform of an audio voice, call the AGetVoicePosition or ASetVoicePosition routines. The playing position of the voices is specified as an offset from the start of the waveform data measured in samples.
Environment Management
To retrieve or set the volume at which a waveform is being played by a particular audio voice your application can call the AGetVoiceVolume and ASetVoiceVolume routines, respectively.
Similarly, by calling the AGetVoiceFrequency and ASetVoiceFrequency routines, you can retrieve and set the sampling frequency at which the audio waveform is being resampled and played by a given audio voice.
To retrieve and set the stereo pan position of an audio voice, your application can call the AGetVoicePanning and ASetVoicePanning routines. These routines have no effect when the system is playing in monophonic format.
Retrieving State Information
The AGetVoiceStatus routine can be used by your application to determine the current state of an audio voice. The returned boolean value is true when the voice is stopped. Notice that a voice will never stop playing a looped waveform unless the AStopVoice is called.
Audio Waveform Interface
Creating Waveforms
Your application can load waveform files directly from disk by calling ALoadWaveFile. The routine AFreeWaveFile is called to release the waveform from memory. It's also possible to create and destroy custom waveforms calling the ACreateAudioData and ADestroyAudioData routines, respectively. Your application can't release a waveform while it's being played by one or more audio voices.
Playing Waveforms
The waveform objects, that represent audio data of individual sound sources such as musical instruments or sound effects, can be played through audio voices calling the APlayVoice or APrimeVoice routines. See the Audio Voices Interface section for more information.
Audio Music Module Interface
Creating Modules
Your application can load music module files directly from disk by calling ALoadModuleFile. The routine AFreeModuleFile is used to release modules from system memory. If the module file is being played by the audio system, your application must stop it to be able to release it from memory.
Play Management
The APlayModule routine is used to select and start playing a music module. The audio system can't play music modules concurrently, but there is no limit in the amount of modules loaded in system memory. The AStopModule routine is called to stop playing the current music module, and to be able to select another module for playback or whenever the module is going to be released from memory.
While a music module is being played by the audio system, your application can control the real-time playback of the module by calling the APauseModule and AResumeModule routines to pause or resume playing the music sequence.
Environment Management
Your application can retrieve or set the current module position by calling the AGetModulePosition and ASetModulePosition routines. These positions are measured in orders and pattern rows.
Similarly, the AGetModuleVolume and ASetModuleVolume routines can be used by your application to change the global volume at which the audio system is playing the music sequence. These routines can only be called while a music module is active.
Reference Guide
Functions
UINT AIAPI Ainitialize(VOID)
Initializes the Synthetic Audio Library.
Returns zero on success.
This routine must be called to initialize the audio system, after initialization your application can use the audio system API routines. It's not required to initialize the audio system for applications running in Windows 95 or Windows NT.
See also AOpenAudio, ACloseAudio
UINT AIAPI AGetVersion(VOID)
Retrieves the Synthetic Audio Library version.
Returns the audio system major and minor version numbers.
This routine can be used by your application to get the audio system version number, the major version number is encoded in the most significant byte of the returned value and the minor version number in the least significant byte.
UINT AIAPI AGetAudioNumDevs(VOID)
Retrieves number of installed audio device drivers.
Returns the number of device drivers installed on the system.
This routine can be used by your application to enumerate the installed audio device drivers on the system. The AGetAudioDevCaps routine can be used to retrieve information from a particular audio device driver.
See also AGetAudioDevCaps
UINT AIAPI AGetAudioDevCaps(UINT nDeviceId, LPAUDIOCAPS lpCaps)
Retrieves information about audio device drivers.
Return zero on success.
- nDeviceId
Audio device driver identifier.
- lpCaps
Address of an AUDIOCAPS structure that will hold the capabitilies information of the audio device driver referenced by the nDeviceId device driver identifier.
This routine retrieves the audio capabilities information from an audio device driver identified by the nDevideId parameter. The AGetAudioNumDevs returns the number of installed audio devices on the system.
VOID PrintAudioDevs(VOID)
{
AUDIOCAPS caps;
UINT nDeviceId;
/* show all the installed device drivers */
for (nDeviceId = 0; nDeviceId < AGetAudioNumDevs(); nDeviceId++) {
AGetAudioDevCaps(nDeviceId, &caps);
printf("nDeviceId=%d wProductId=%d szProductName=%s\n",
nDeviceId, caps.wProductId, caps.szProductName);
}
}
See also AGetAudioNumDevs
UINT AIAPI AGetErrorText(UINT nErrorCode, LPSTR lpText, UINT nSize)
Return readable text description for a given error return code.
Return zero on success.
- nErrorCode
Numeric error return code to be translated.
- lpText
Address of the null-terminated text description buffer.
- nSize
Number of bytes of the text description buffer.
Most of the routines in the Synthetic Audio Library return numeric error codes which can be translated to a readable text description using this routine. The returned text description is a null-terminated string of ASCII characters.
VOID InitializeAudio(VOID)
{
AUDIOINFO info;
CHAR szText[128];
UINT rc;
info.nDeviceId = AUDIO_DEVICE_MAPPER;
info.wFormat = AUDIO_FORMAT_16BITS | AUDIO_FORMAT_STEREO;
info.nSampleRate = 44100;
if ((rc = AOpenAudio(&info)) != AUDIO_ERROR_NONE) {
AGetErrorText(rc, szText, sizeof(szText) - 1);
printf("ERROR: %s\n", szText);
exit(1);
}
}
UINT AIAPI APingAudio(LPUINT lpnDeviceId)
Automatically detect the installed audio device.
Returns zero on success.
- lpnDeviceId
Address of an unsigned integer that will hold the detect device identifier.
This routine can be used to determine which audio device is present on the system. Alternatively, your application can detect and use an audio device by using the virtual audio device identifer AUDIO_DEVICE_MAPPER to open the audio system with the AOpenAudio routine.
VOID DetectAudioDevice(VOID)
{
AUDIOCAPS caps;
UINT nDeviceId;
if (APingAudio(&nDeviceId) != AUDIO_ERROR_NONE) {
printf("no audio device found.\n");
}
else {
AGetAudioDevCaps(nDeviceId, &caps);
printf("%s device found.\n", caps.szProductName);
}
}
See Also AOpenAudio, AGetAudioDevCaps
UINT AIAPI AOpenAudio(LPAUDIOINFO lpInfo)
Open audio device for playback.
Returns zero on success.
- lpInfo
Address of an AUDIOINFO structure that holds the playback configuration.
This routine open a given audio device for playback at the specified format and sampling frequency. Since the hardware device might not support the desired configuration, the audio system will use the closest parameters which are then returned in the AUDIOINFO structure.
VOID InitializeAudio(VOID)
{
AUDIOINFO info;
info.nDeviceId = AUDIO_DEVICE_MAPPER;
info.wFormat = AUDIO_FORMAT_16BITS | AUDIO_FORMAT_STEREO;
info.nSampleRate = 44100;
if (AOpenAudio(&info) != AUDIO_ERROR_NONE) {
printf("Audio initialization failed.\n");
exit(1);
}
else {
printf("Audio device initialized at %d bits %s %u Hz\n",
info.wFormat & AUDIO_FORMAT_16BITS ? 16 : 8,
info.wFormat & AUDIO_FORMAT_STEREO ?
"stereo": "mono", info.nSampleRate);
}
}
See Also ACloseAudio, AUpdateAudio
UINT AIAPI ACloseAudio(VOID)
Close the audio device.
Returns zero on success.
This routine must be called to close the audio device before leaving from your application. Your application must release all the resources allocated before closing the audio system.
See Also AOpenAudio, AUpdateAudio
UINT AIAPI AUpdateAudio(VOID)
Updates the audio system output buffers.
Returns zero on success.
This routine must be called periodically by your application to update the audio buffers which are sent to the hardware for playback. If your application fails to call this routine enough times per second, the audio output will sound like a broken disc. It's not required to call this routine for Windows 95 and Windows NT applications.
See Also AOpenAudio, ACloseAudio, AUpdateAudioEx
UINT AIAPI AUpdateAudioEx(UINT nFrames)
Updates the audio system output buffers.
Returns zero on success.
- nFrames
The maximum amount of sample frames to update in the output buffer.
This routine is similar to AUpdateAudio but lets you have more control on the latency of the audio system. It must be called to update up to nFrames sample frames in the output buffer. For example, every time you call AUpdateAudioEx(nSampleRate/100) the audio system will fill up to 10 ms of sound in the output buffer.
See Also AOpenAudio, ACloseAudio, AUpdateAudio
UINT AIAPI ASetAudioMixerValue(UINT nChannel, UINT nValue)
Changes the audio mixer settings.
Returns zero on success.
- nChannel
The mixer channel identifier.
- nValue
The new mixer channel's value (0-256).
This routine changes the mixer level settings of the audio engine. Currently the only channel supported is the AUDIO_MIXER_MASTER_VOLUME channel which sets the overall mixing volume level for all the audio voices.
UINT AIAPI ASetAudioCallback(LPFNAUDIOWAVE lpfnAudioWave)
Install audio wave callback routine. Internal use only.
Returns zero on success.
This routine is used internally by the audio system to install the audio wave callback routine used by the software wavetable synthesizer to fill the hardware DMA audio buffer with samples.
UINT AIAPI ASetAudioTimerProc(LPFNAUDIOTIMER lpfnAudioTimer)
Install virtual audio timer callback routine.
Returns zero on success.
- lpfnAudioTimer
Address of the timer handler routine.
This routine set the virtual audio timer callback routine. Since the audio system uses this timer to play module files in background, your application should not use this routine while the system is playing a music sequence. The virtual timer callback can be called from a hardware interrupt handler for applications running in DOS.
volatile UINT nTickCounter = 0;
VOID AIAPI TimerHandler(VOID)
{
nTickCounter++;
}
VOID InitTimerHandler(VOID)
{
/* the handler will be called at 125 BPM (50 times per second) */
ASetAudioTimerProc(TimerHandler);
ASetAudioTimerRate(125);
}
VOID DoneTimerHandler(VOID)
{
ASetAudioTimerProc(NULL);
}
See Also ASetAudioTimerRate
UINT AIAPI ASetAudioTimerRate(UINT nTimerRate)
Changes the virtual audio timer rate.
Returns zero on success.
- nTimerRate
The timer rate given in beats per minute (32-255).
This routine changes the rate at which the virtual audio timer callback will be called by the audio system. Since the virtual audio timer is used by the system to play music sequences, your application can change the tempo or speed of the music by calling this routine while the module is being played.
See Also ASetAudioTimerProc
UINT AIAPI AOpenVoices(UINT nVoices)
Open audio voices.
Returns zero on success.
- nVoices
Maximum number of allocatable audio voices (1-32).
This routine is used to open audio voices for playback. The number of opened voices may affect both the performance and sound quality for some audio devices, so your application should allocate the minimum amount of voices. Your application must call the routine ACloseVoices to close all the audio voices before exiting or when the number of opened voices need to be changed.
See Also ACloseVoices, ACreateAudioVoice, ADestroyAudioVoice
UINT AIAPI ACloseVoices(VOID)
Close all the audio voices.
Returns zero on success.
This routine closes all the active audio voices. Before calling this routine, all the allocated voices, including those allocated indirectly by calling the APlayModule routine, must be released.
See Also AOpenVoices, ACreateAudioVoice, ADestroyAudioVoice
UINT AIAPI ACreateAudioVoice(LPHAC lphVoice)
Allocates a single audio voice.
Returns zero on success.
- lphVoice
Address of a voice handle that will hold the allocated voice.
This routine allocates an audio voice which can be used by your application to play waveforms through it. The routine will fail if no more voices are availables or if the application has not yet called AOpenVoices to open audio voices.
VOID PlayWaveform(LPAUDIOWAVE lpWave)
{
HAC hVoice;
BOOL stopped;
/* allocate an audio voice or channel */
if (ACreateAudioVoice(&hVoice) == AUDIO_ERROR_NONE) {
/* play the waveform through the voice */
APlayVoice(hVoice, lpWave);
ASetVoiceVolume(hVoice, 64);
ASetVoicePanning(hVoice, 128);
/* wait until the wave finishes or a key is pressed */
while (!kbhit()) {
AUpdateAudio();
AGetVoiceStatus(hVoice, &stopped);
if (stopped) break;
}
/* stop the voice (if already playing) */
AStopVoice(hVoice);
/* release the allocated voice */
ADestroyAudioVoice(hVoice);
}
}
See Also AOpenVoices, ACloseVoices, ADestroyAudioVoice
UINT AIAPI ADestroyAudioVoice(HAC hVoice)
Releases an allocated audio voice.
Returns zero on success.
- hVoice
Handle of the audio voice which will be released.
This routine releases an audio voice that was previously allocated by calling the ACreateAudioVoice routine. Your application should not release voices which are currently being used to play a waveform.
See Also ACreateAudioVoice
UINT AIAPI APlayVoice(HAC hVoice, LPAUDIOWAVE lpWave)
Start playing a waveform through a voice.
Returns zero on success.
- hVoice
Handle of the audio voice that will play the waveform.
- lpWave
Address of the waveform structure to be played.
This routine start playing a waveform through an audio voice at the default sampling frequency. The volume and panning settings of the audio voice are not changed, so your application may need to change these parameters manually.
See Also APrimeVoice, AStartVoice, AStopVoice
UINT AIAPI APrimeVoice(HAC hVoice, LPAUDIOWAVE lpWave)
Prepares a waveform on an audio voice.
Returns zero on success.
- hVoice
Handle of the audio voice that will be prepared.
- lpWave
Address of the waveform structure that will be played.
This routine is similar to APlayVoice but will only prepare a waveform to be played through a voice. The routine AStartVoice must be called to actually start playing the waveform. The frequency, volume and panning settings of the voice are not changed by this routine.
VOID PlayChord(HAC aVoices[3], LPAUDIOWAVE lpWave, LONG aFreqs[3])
{
UINT n;
/* first prepare the voices to play the waveform */
for (n = 0 ; n < 3 ; n++) {
APrimeVoice(aVoices[n], lpWave);
ASetVoiceFrequency(aVoices[n], aFreqs[n]);
ASetVoiceVolume(aVoices[n], 64);
}
/* now start playing all them simultaneously */
for (n = 0 ; n < 3 ; n++) {
AStartVoice(aVoices[n]);
}
}
See Also APlayVoice, AStartVoice, AStopVoice
UINT AIAPI AStartVoice(HAC hVoice)
Start playing an audio voice.
Returns zero on success.
- hVoice
Handle of the audio voice to be started.
This routines starts or continues playing a waveform through an audio voice that was prepared or stopped by the APrimeVoice or AStopVoice routines.
See Also APrimeVoice, APlayVoice, AStopVoice
UINT AIAPI AStopVoice(HAC hVoice)
Stop playing an audio voice.
Returns zero on success.
- hVoice
Handle of the audio voice to be stopped.
This routine stop an audio voice. Your application can restart the audio voice by calling the AStartVoice routine, the voice will continue playing the waveform starting at the position where it was previously stopped.
See Also APrimeVoice, APlayVoice, AStartVoice
UINT AIAPI ASetVoicePosition(HAC hVoice, LONG dwPosition)
Changes the voice playing position.
Returns zero on success.
- hVoice
Handle of an audio voice.
- dwPosition
Playing position measured in samples.
This routine changes the playing position of an audio voice. The position will be changed in real-time, so your application can program echo effects using a pair of allocated voices, for example.
VOID PlayEchoVoices(HAC aVoices[2], LPAUDIOWAVE lpWave, LONG dwDelay)
{
/* prepare two voices with the same waveform */
APrimeVoice(aVoices[0], lpWave);
APrimeVoice(aVoices[1], lpWave);
ASetVoiceFrequency(aVoices[0], lpWave->nSampleRate);
ASetVoiceFrequency(aVoices[1], lpWave->nSampleRate);
/* set voice volumes (the "echo" voice has a lower volume) */
ASetVoiceVolume(aVoices[0], 64);
ASetVoiceVolume(aVoices[1], 32);
/* set the delay (measured in samples) for the "echo" voice */
ASetVoicePosition(aVoices[1], dwDelay);
/* start both voices as simultenously as possible */
AStartVoice(aVoices[0]);
AStartVoice(aVoices[1]);
}
See Also AGetVoicePosition
UINT AIAPI ASetVoiceFrequency(HAC hVoice, LONG dwFrequency)
Changes the voice sampling frequency.
Returns zero on success.
- hVoice
Handle of the audio voice to be changed.
- dwFrequency
Sampling frequency measured in Hertz (cycles per second).
This routine changes the sampling frequency of an audio voice. Your application can use this routine to do things like pitch slides or simple stereo enhancement effects by changing the frequency of the audio voices in real-time.
VOID PlayVoiceStereo(HAC aVoices[2], LPAUDIOWAVE lpWave, LONG dwPitchShift)
{
/* prepare two voices to play a waveform */
APrimeVoice(aVoices[0], lpWave);
APrimeVoice(aVoices[1], lpWave);
ASetVoiceVolume(aVoices[0], 64);
ASetVoiceVolume(aVoices[1], 64);
/* slightly change the pitch of one of the voices */
ASetVoiceFrequency(aVoices[0], lpWave->nSampleRate);
ASetVoiceFrequency(aVoices[1], lpWave->nSampleRate + dwPitchShift);
/* set the pan position of the voices to left and right */
ASetVoicePanning(aVoices[0], 0);
ASetVoicePanning(aVoices[1], 255);
/* start both voices simultaneously */
AStartVoice(aVoices[0]);
AStartVoice(aVoices[1]);
}
See Also AGetVoiceFrequency
UINT AIAPI ASetVoiceVolume(HAC hVoice, UINT nVolume)
Changes the voice volume level.
Returns zero on success.
- hVoice
Handle of the audio voice to be changed.
- nVolume
Linear volume level (0-64).
This routine changes the volume level of an audio voice. The voices can be faded in and out smoothly in real-time using this routine and the virtual audio timer services, for example.
See Also AGetVoiceVolume
UINT AIAPI ASetVoicePanning(HAC hVoice, UINT nPanning)
Changes the voice stereo pan position.
Returns zero on success.
- hVoice
Handle of the audio voice to be changed.
- nPanning
Stereo pan position value (0-255).
This routine changes the stereo pan position of an audio voice. It has no effect when the audio system is playing in monophonic mode.
See Also AGetVoicePanning
UINT AIAPI AGetVoicePosition(HAC hVoice, LPLONG lpdwPosition)
Retrieves the playing position of a voice.
Returns zero on success.
- hVoice
Handle of the audio voice to be queried.
- lpdwPosition
Address of a long variable which will hold the playing position.
This routine retrieves the current playing position of an audio voice measured in samples. Your application can use this routine to implement a double buffering algorithm to play streams of audio data from disk using a single audio voice.
See Also ASetVoicePosition
UINT AIAPI AGetVoiceFrequency(HAC hVoice, LPLONG lpdwFrequency)
Retrieves the sampling frequency of a voice.
Returns zero on success.
- hVoice
Handle of the audio voice to be queried.
- lpdwFrequency
Address of a long variable that will hold the frequency.
This routine retrieves the current sampling frequency of an audio voice. Your application should not expect to get back the same frequency used in the last call to the ASetVoiceFrequency routine, due to possible rounding errors that occur when the audio system translates frequencies in Hertz to the device dependant format used by the hardware audio device.
See Also ASetVoiceFrequency
UINT AIAPI AGetVoiceVolume(HAC hVoice, LPUINT lpnVolume)
Retrieves the volume level of a voice.
Returns zero on success.
- hVoice
Handle of the audio voice to be queried.
- lpnVolume
Address of an unsigned integer variable that will hold the volume.
This routine retrieves the current volume level of an audio voice. Your application should not expect to get back the same volume level used in the last call to the ASetVoiceVolume routine, due to possible rounding errors that occur when the audio system translates linear volumes to the device dependant format used by the hardware audio device.
See Also ASetVoiceVolume
UINT AIAPI AGetVoicePanning(HAC hVoice, LPUINT lpnPanning)
Retrieves the stereo pan position of a voice.
Returns zero on success.
- hVoice
Handle of the audio voice which will be queried.
- lpnPanning
Address of an unsigned integer variable that will hold the pan position.
This routine retrieves the current stereo pan position of an audio voice. Your application should not expect to get back the same pan position used in the last call to the ASetVoicePanning routine, due to possible rounding errors that occur when the audio system translates pan positions to the device dependant format used by the hardware audio device.
See Also ASetVoicePanning
UINT AIAPI AGetVoiceStatus(HAC hVoice, LPBOOL lpbStatus)
Retrieves the current status of a voice.
Returns zero on success.
- hVoice
Handle of the audio voice that will be queried.
- lpbStatus
Address of a boolean variable that will hold the voice status.
This routine retrieves the current status of an audio voice. Your application can use this routine to determine if a voice is stopped or if it's playing a waveform.
VOID CheckVoice(HAC hVoice)
{
BOOL stopped;
AGetVoiceStatus(hVoice, &stopped);
if (stopped)
printf("voice is stopped.\n");
}
See Also AStartVoice, AStopVoice
LONG AIAPI AGetAudioDataAvail(VOID)
Retrieves the amount of available DRAM memory.
Returns amount of available DRAM memory (in bytes).
This routine retrieves the number of free bytes on the hardware audio device when applicable. It can be used to determine if there is enough space to hold a set of samples or waveforms simultaneously. It returns zero when the audio system is using system memory to hold the audio waveforms data.
VOID ShowFreeMemory(VOID)
{
LONG dwMemFree;
dwMemFree = AGetAudioDataAvail();
printf("%ld bytes free.\n", dwMemFree);
}
UINT AIAPI ACreateAudioData(LPAUDIOWAVE lpWave)
Creates a waveform object.
Returns zero on success.
- lpWave
Address of the waveform structure.
This routine is used to create custom waveform objects. Your application can also use ALoadWaveFile to load RIFF/WAVE waveform files from disk. The current version of the audio system only support 8 and 16 bit mono one-shot or looped waveforms (reverse and bidirectional looping modes are not supported by AWE32 audio devices).
LPAUDIOWAVE CreateAudio8BitMono(WORD nSampleRate,
LPBYTE lpData, DWORD dwLength)
{
LPAUDIOWAVE lpWave;
/* first allocate structure to hold the waveform object */
if ((lpWave = (LPAUDIOWAVE) malloc(sizeof(AUDIOWAVE))) != NULL) {
/* create a 8-bit mono one-shot waveform object */
lpWave->wFormat = AUDIO_FORMAT_8BITS | AUDIO_FORMAT_MONO;
lpWave->nSampleRate = nSampleRate;
lpWave->dwLength = dwLength;
lpWave->dwLoopStart = lpWave->dwLoopEnd = 0;
if (ACreateAudioData(lpWave) != AUDIO_ERROR_NONE) {
free(lpWave);
return NULL;
}
/* copy the data into the waveform object */
memcpy(lpWave->lpData, lpData, dwLength);
/* upload the data to the audio DRAM local memory */
AWriteAudioData(lpWave, 0L, dwLength);
}
return lpWave;
}
The waveform structure fields dwLength, dwLoopStart and dwLoopEnd are all measured in bytes, not samples, so your application should be careful to handle 16 bit waveform objects.
See Also ADestroyAudioData, AWriteAudioData
UINT AIAPI ADestroyAudioData(LPAUDIOWAVE lpWave)
Releases a waveform object.
Returns zero on success.
- lpWave
Address of the waveform object to be released.
This routine releases a waveform object previously allocated by calling the ACreateAudioData routine. Before releasing any waveform, your application must be sure that no voices are currently playing the waveform.
See Also ACreateAudioData, AWriteAudioData
UINT AIAPI AWriteAudioData(LPAUDIOWAVE lpWave, DWORD dwOffset, UINT nCount)
Upload waveform audio data to DRAM local memory.
Returns zero on success.
- lpWave
Address of the waveform object.
- dwOffset
Starting offset of the block of samples to be uploaded.
- nCount
Number of bytes in the block of samples to be transferred.
This routine uploads a block of samples from system memory to the hardware DRAM local memory when applicable. Your application must call this routine everytime it writes to the waveform audio data. The chunk of samples to be uploaded is specified by the offset and count parameters measured in bytes.
VOID StreamData8BitMono(FILE *stream, HAC hVoice, LPAUDIOWAVE lpWave)
{
BYTE aBuffer[1024];
LPBYTE lpChunk;
UINT nLength, nChunkSize;
DWORD dwOffset, dwVoicePosition;
/* check if the waveform is large enough for double buffering */
if (2*sizeof(aBuffer) > lpWave->dwLength) {
printf("the waveform is too small\n");
return;
}
/* first clean up the audio waveform buffer */
memset(lpWave->lpData, 0x80, lpWave->dwLength);
AWriteAudioData(lpWave, 0L, lpWave->dwLength);
/* start playing the waveform with forward looping enabled */
lpWave->wFormat |= AUDIO_FORMAT_LOOP;
lpWave->dwLoopStart = 0L;
lpWave->dwLoopEnd = lpWave->dwLength;
APlayVoice(hVoice, lpWave);
ASetVoiceVolume(hVoice, 64);
/* play the whole 8-bit mono stream of audio through the voice */
dwOffset = 0;
while ((nLength = fread(aBuffer, 1, nLength, stream)) != 0) {
/* write the waveform audio data in chunks */
lpChunk = aBuffer;
while (nLength > 0) {
/* determine size of chunk of data */
nChunkSize = nLength;
if (dwOffset + nChunkSize >= lpWave->dwLength)
nChunkSize = lpWave->dwLength - dwOffset;
/* wait until we can write the chunk of data */
for (;;) {
AUpdateAudio();
AGetVoicePosition(hVoice, &dwVoicePosition);
if (dwOffset + nChunkSize > lpWave->dwLength) {
if (dwVoicePosition < dwOffset &&
dwVoicePosition > dwOffset +
nChunkSize - lpWave->dwLength)
break;
}
else {
if (dwVoicePosition < dwOffset ||
dwVoicePosition > dwOffset + nChunkSize)
break;
}
}
/* upload the chunk of waveform data */
memcpy(lpWave->lpData + dwOffset, lpChunk, nChunkSize);
AWriteAudioData(lpWave, dwOffset, nChunkSize);
if ((dwOffset += nChunkSize) >= lpWave->dwLength)
dwOffset = 0;
lpChunk += nChunkSize;
nLength -= nChunkSize;
}
}
}
See Also ACreateAudioData, ADestroyAudioData
UINT AIAPI ALoadWaveFile(LPSTR lpszFileName, LPAUDIOWAVE* lplpWave, DWORD dwOffset)
Load a RIFF/WAVE waveform file from disk.
Returns zero on success.
- lpszFileName
Filename of the .WAV waveform file on disk.
- lplpWave
Address of a pointer to a waveform structure.
- dwOffset
Starting file offset of the waveform file.
This routine load a RIFF/WAVE waveform from disk. The loaded waveform must be released with the AFreeWaveFile routine.
VOID PlayWaveFile(HAC hVoice, LPSTR lpszFileName)
{
LPAUDIOWAVE lpWave;
BOOL stopped;
if (ALoadWaveFile(lpszFileName, &lpWave, 0L) == AUDIO_ERROR_NONE) {
APlayVoice(hVoice, lpWave);
ASetVoiceVolume(hVoice, 64);
while (!kbhit()) {
AUpdateAudio();
AGetVoiceStatus(hVoice, &stopped);
if (stopped) break;
}
AFreeWaveFile(lpWave);
}
}
See Also AFreeWaveFile
UINT AIAPI AFreeWaveFile(LPAUDIOWAVE lpWave)
Releases a loaded RIFF/WAVE waveform file.
Returns zero on success.
- lpWave
Address of the waveform structure to be released.
This routine releases waveform files loaded from disk. Your application can't use ADestroyAudioData to release waveforms loaded from disk. You must stop any voice that is playing the waveform before releasing it.
See Also ALoadWaveFile
UINT AIAPI APlayModule(LPAUDIOMODULE lpModule)
Start playing a music module file.
Returns zero on success.
- lpModule
Address of the module to be played.
This routine start playing a module file in background using the audio system module player. Your application can stop a module by calling the AStopModule routine. The application must have enough available audio voices to play the music module.
See Also AStopModule
UINT AIAPI AStopModule(VOID)
Stop playing a music module file.
Returns zero on success.
This routine stop and releases the audio system module player. After calling this routine, your application can select and start another module by calling the APlayModule routine.
See Also APlayModule
UINT AIAPI APauseModule(VOID)
Stop playing a music module file.
Returns zero on success.
This routine stop the audio system module player. You can later continue playing the music module by calling the AResumeModule routine. Your application must use AStopModule when the currently select module file is going to be released, or if another music module must be played.
See Also APlayModule, AStopModule, AResumeModule
UINT AIAPI AResumeModule(VOID)
Restart playing a music module file.
Returns zero on success.
This routine is used to continue playing a music module that was previously paused by the APauseModule routine. Your application can use AGetModuleStatus to retrieve the current state of the audio system module player.
See Also APlayModule, AStopModule, APauseModule, AGetModuleStatus
UINT AIAPI ASetModuleVolume(UINT nVolume)
Changes the music module global volume.
Returns zero on success.
- nVolume
The new volume level for the music module (0-64).
This routine changes the global volume at which the audio system is playing a music module sequence.
See Also APlayModule, AStopModule, AGetModuleVolume
UINT AIAPI ASetModulePosition(UINT nOrder, UINT nRow)
Changes the music module playing position.
Returns zero on success.
- nOrder
The new order position.
- nRow
The new pattern row number.
This routine changes the playing position of the audio system module player. Your application can use this routine to play small music sequences or patterns of sound effects, intro music, etc. all of them stored in the same music module file.
See Also APlayModule, AStopModule, AGetModulePosition
UINT AIAPI AGetModuleVolume(LPUINT lpnVolume)
Retrieves the music module global volume.
Returns zero on success.
- lpnVolume
Address of an unsigned integer that will hold the module volume.
This routine retrieves the global volume used by the audio system to play a music module sequence.
See Also APlayModule, AStopModule, ASetModuleVolume
UINT AIAPI AGetModulePosition(LPUINT lpnOrder, LPUINT lpnRow)
Retrieves the music module playing position.
Returns zero on success.
- lpnOrder
Address of an unsigned integer that will hold the order position.
- lpnRow
Address of an unsigned integer that will hold the pattern row number.
This routine retrieves the playing position of the audio system module player. Your application can use this routine to synchronize graphics or video with the music.
See Also APlayModule, AStopModule, ASetModulePosition
UINT AIAPI AGetModuleStatus(LPBOOL lpbStatus)
Retrieves the current state of the music module player.
Returns zero on success.
- lpbStatus
Address of an unsigned integer that will hold the status.
This routine retrieves the current status of the audio system module player. The routine returns true if the module player is paused or false otherwise. The audio system pauses the module file when the APauseModule routine is called or when the end of a non-looped music sequence is reached.
See Also APlayModule, AStopModule, APauseModule, AResumeModule
UINT AIAPI ASetModuleCallback(LPFNAUDIOCALLBACK lpfnAudioCallback)
Changes the music module synchronization callback routine.
Returns zero on success.
- lpfnAudioCallback
Address of the synchronization callback routine.
This routine changes the synchronization routine that is called by the audio system module player whenever it encounters a synchronization mark in the pattern effects column, the argument of the effect is passed to the callback routine. For ScreamTracker 3.0 and FastTracker 2.0 modules, the command effect Znn is used for synchronization (where nn is an hexadecimal number passed to the synchronization callback routine). For applications running under DOS, the synchronization callback can be called from within a hardware interrupt handler routine.
#define START_INTRO_SEQUENCE 0x01 /* Z01 */
#define START_VECTOR_GRAPHICS 0x02 /* Z02 */
VOID AIAPI SyncCallback(BYTE nParms, UINT nOrder, UINT nRow)
{
switch (nParms) {
case START_INTRO_SEQUENCE:
StartIntroSequence();
break;
case START_VECTOR_GRAPHICS:
StartVectorGraphics();
break;
default:
/* unknown Znn command found at position (nOrder, nRow) */
break;
}
}
VOID InitSyncCallback(VOID)
{
ASetModuleCallback(SyncCallback);
}
VOID DoneSyncCallback(VOID)
{
ASetModuleCallback(NULL);
}
UINT AIAPI ALoadModuleFile(LPSTR lpszFileName, LPAUDIOMODULE* lplpModule, DWORD dwOffset)
Load MOD/MTM/S3M/XM module files from disk.
Returns zero on success.
- lpszFileName
File name of the music module file.
- lplpModule
Address of a music module reference variable.
- dwOffset
Starting file offset of the music module file.
This routine loads MOD/MTM/S3M/XM music module files from disk. The music module can be played and stopped by calling the APlayModule and AStopModule routines, respectively.
See Also AFreeModuleFile
UINT AIAPI AFreeModuleFile(LPAUDIOMODULE lpModule)
Releases a music module file from memory.
Returns zero on success.
- lpModule
Address of a music module file in memory.
This routine releases music module files from memory previously loaded by the ALoadModuleFile routine. Your application can't release modules currently being played by the audio system.
See Also ALoadModuleFile
Structures
AUDIOCAPS
typedef struct {
WORD wProductId;
CHAR szProductName[30];
DWORD dwFormats;
} AUDIOCAPS, *LPAUDIOCAPS;
The AUDIOCAPS structure contains the audio capabilities information that can be obtained by calling AGetAudioDevCaps for a given audio device driver.
Members:
- wProductId
Specifies the hardware audio device product identifier. This member can hold any of the following values:
Value | Description |
AUDIO_PRODUCT_NONE | Virtual silence device |
AUDIO_PRODUCT_SB | Sound Blaster 1.0 device |
AUDIO_PRODUCT_SB15 | Sound Blaster 1.5 device |
AUDIO_PRODUCT_SB20 | Sound Blaster 2.0 device |
AUDIO_PRODUCT_SBPRO | Sound Blaster Pro I or II device |
AUDIO_PRODUCT_SB16 | Sound Blaster 16/ASP device |
AUDIO_PRODUCT_AWE32 | Sound Blaster AWE32 device |
AUDIO_PRODUCT_WSS | Windows Sound System device |
AUDIO_PRODUCT_ESS | Ensoniq Soundscape (Elite) device |
AUDIO_PRODUCT_GUS | Gravis Ultrasound (GF1) device |
AUDIO_PRODUCT_GUSDB | Gravis Ultrasound Daughterboard device |
AUDIO_PRODUCT_GUSMAX | Gravis Ultrasound Max (CS4231) device |
AUDIO_PRODUCT_IWAVE | AMD Interwave-based device |
AUDIO_PRODUCT_PAS | Pro Audio Spectrum (Plus) device |
AUDIO_PRODUCT_PAS16 | Pro Audio Spectrum 16 device |
AUDIO_PRODUCT_ARIA | Sierra Semiconductors Aria Sound device |
AUDIO_PRODUCT_WINDOWS | Microsoft Windows WAVE device |
AUDIO_PRODUCT_DSOUND | Microsoft Windows DirectSound device |
AUDIO_PRODUCT_LINUX | UNIX Sound System for Linux device |
AUDIO_PRODUCT_SPARC | SPARC workstation 8-bit ulaw or dbri device |
AUDIO_PRODUCT_SGI | Silicon Graphics Indigo Audio Ports device |
AUDIO_PRODUCT_OS2MMPM | OS/2 Multimedia Presentation Manager device |
AUDIO_PRODUCT_OS2DART | OS/2 DART Real Time Audio device |
AUDIO_PRODUCT_BEOSR3 | BeOS Release 3 OLD MediaKit device |
AUDIO_PRODUCT_BEOS | BeOS Release 4 New MediaKit device |
- szProductName
Null terminated readable text string describing the hardware audio device product.
- dwFormats
Specifies the playback formats supported by the hardware audio device product. This member can be built using any combination of the following values:
Value | Description |
AUDIO_FORMAT_1M08 | 8-bit mono 11025 Hz |
AUDIO_FORMAT_1S08 | 8-bit stereo 11025 Hz |
AUDIO_FORMAT_1M16 | 16-bit mono 11025 Hz |
AUDIO_FORMAT_1S16 | 16-bit stereo 11025 Hz |
AUDIO_FORMAT_2M08 | 8-bit mono 22050 Hz |
AUDIO_FORMAT_2S08 | 8-bit stereo 22050 Hz |
AUDIO_FORMAT_2M16 | 16-bit mono 22050 Hz |
AUDIO_FORMAT_2S16 | 16-bit stereo 22050 Hz |
AUDIO_FORMAT_4M08 | 8-bit mono 44100 Hz |
AUDIO_FORMAT_4S08 | 8-bit stereo 44100 Hz |
AUDIO_FORMAT_4M16 | 16-bit mono 44100 Hz |
AUDIO_FORMAT_4S16 | 16-bit stereo 44100 Hz |
AUDIOINFO
typedef struct {
UINT nDeviceId;
WORD wFormat;
WORD nSampleRate;
} AUDIOINFO, *LPAUDIOINFO;
Audio information structure used to open the hardware audio device for playback by using the AOpenAudio routine.
Members:
- nDeviceId
Specifies the audio device we want to use for playback. The following virtual audio device identifiers are always defined:
Value | Description |
AUDIO_DEVICE_NONE | Silence device driver |
AUDIO_DEVICE_MAPPER | Audio mapper driver |
- wFormat
Specifies the audio output format for playback. This member can be built using the following values:
Value | Description |
AUDIO_FORMAT_8BITS | 8 bits per sample |
AUDIO_FORMAT_16BITS | 16 bits per sample |
AUDIO_FORMAT_MONO | Monophonic output |
AUDIO_FORMAT_STEREO | Stereo output |
AUDIO_FORMAT_FILTER | Enable filtering |
- nSampleRate
Specifies the sampling frequency used for playback. It's recommended to use the standard frequencies 11025, 22050 or 44100 Hz for better compatibility.
AUDIOWAVE
typedef struct {
LPBYTE lpData;
DWORD dwHandle;
DWORD dwLength;
DWORD dwLoopStart;
DWORD dwLoopEnd;
WORD nSampleRate;
WORD wFormat;
} AUDIOWAVE, *LPAUDIOWAVE;
Audio waveform structure used to hold all the information related to a single waveform.
Members:
- lpData
Read Only. Address of the a buffer in system memory used to hold the waveform data.
- dwHandle
Read Only. Handle used internally by the audio device drivers to reference the waveform data.
- dwLength
Specifies the length in bytes of the waveform data.
- dwLoopStart
Specifies the loop start point measured in bytes, only used for looped samples.
- dwLoopEnd
Specifies the loop end point measured in bytes, only used for looped samples.
- nSampleEate
The default sampling frequency of the waveform data.
- wFormat
Specifies the format and the looping type of the waveform data. This member can be built using the following defines:
Value | Description |
AUDIO_FORMAT_8BITS | 8 bits per sample |
AUDIO_FORMAT_16BITS | 16 bits per sample |
AUDIO_FORMAT_MONO | Monophonic output |
AUDIO_FORMAT_STEREO | Stereo output |
AUDIO_FORMAT_LOOP | Forward looping |
AUDIO_FORMAT_BIDILOOP | Bidirectional looping |
AUDIO_FORMAT_REVERSE | Reverse playing |
AUDIOMODULE
typedef struct {
CHAR szModuleName[32];
WORD wFlags;
WORD nOrders;
WORD nRestart;
WORD nTracks;
WORD nPatterns;
WORD nPatches;
WORD nTempo;
WORD nBPM;
BYTE aOrderTable[AUDIO_MAX_ORDERS];
BYTE aPanningTable[AUDIO_MAX_VOICES];
LPAUDIOPATTERN aPatternTable;
LPAUDIOPATCH aPatchTable;
} AUDIOMODULE, *LPAUDIOMODULE;
This structure holds all the information related to a single music module file loaded in system memory.
Members:
- szModuleName
Specifies the music module name as a null-terminated text string.
- wFlags
Specifies some intial flags for the music module. This member can be built using the following values:
Value | Description |
AUDIO_MODULE_LINEAR | The module uses linear frequencies |
AUDIO_MODULE_AMIGA | Use Amiga logarithmic frequencies |
AUDIO_MODULE_PANNING | Use pan position from instruments |
- nOrders
Number of entries in the sequence order table.
- nRestart
Specifies the restart order position for looped modules.
- nTracks
Number of tracks used in the music module.
- nPatterns
Number of patterns used in the music module.
- nPatches
Number of patches or instruments used in the music module.
- nTempo
Initial speed or tempo value.
- nBPM
Initial BPM or beats per minute value.
- aOrderTable
Specifies the sequence order in which the patterns are played.
- aPanningTable
Initial stereo pan position for all the music module tracks.
- aPatternTable
Array of pattern structures.
- aPatchTable
Array of patches structures.
RETURN CODES
Value | Description |
AUDIO_ERROR_NONE | No error |
AUDIO_ERROR_INVALHANDLE | Invalid voice or waveform handle |
AUDIO_ERROR_INVALPARAM | Invalid parameter passed |
AUDIO_ERROR_NOTSUPPORTED | Invalid audio system call |
AUDIO_ERROR_BADDEVICEID | Invalid device identifier |
AUDIO_ERROR_NODEVICE | No audio device found |
AUDIO_ERROR_DEVICEBUSY | Audio device is busy |
AUDIO_ERROR_BADFORMAT | Bad or unsupported audio playback format |
AUDIO_ERROR_NOMEMORY | Not enough system memory |
AUDIO_ERROR_NODRAMMEMORY | Not enough onboard DRAM memory |
AUDIO_ERROR_FILENOTFOUND | Module or waveform file not found |
AUDIO_ERROR_BADFILEFORMAT | Invalid module or waveform file format |
November 30th, 1998.