Acknowledgments

Discussion

The product name Miles Sound System, the Miles logo, and XMIDI are all copyrighted and trademarked by RAD Game Tools, Inc. Copyright 1991-2007 RAD Game Tools, Inc. All Rights Reserved. Printed and produced in the United States of America.

As a licensee of Miles, you must abide by the terms set forth in your license agreement. Please refer to that agreement if you have any questions about what you may or may not do with this documentation or the software to which it pertains. Miles is not copy protected, but it is copyrighted. We think our license agreements are fair, and that our software is reasonably priced for the quality and effort we have put into it. Using our software in ways other than allowed by your license agreement violates federal, civil, and criminal law. We rely primarily on your good faith not to violate our copyright; please respect it.

This software and documentation are provided "as is" without warranty of any kind, either expressed or implied, including, but not limited to, the implied warranties of merchantability and fitness for a particular purpose. In no event will RAD Game Tools, Inc. be liable to you for damages, including any general, special, incidental or consequential damages arising out of the use or inability to use the product (including, but not limited to, loss of data).

The Miles Sound System was written and designed by John Miles and Jeff Roberts. Special thanks also to Mitch Soule, Alicia Fukunaga, and Casey Muratori!

MP3 optimizations and PS2 assembly by Michael Abrash and Mike Sartain.

Additional programming by Dan Teven. Initial filter programming by Nick Skrepetos.

Thanks to AMD for their kind support during the development of Miles for Windows 64!

Macintosh version originally ported by Software MacKiev (Volodya Prokurashko, Anatoly Klimashevsky, Anton Turov, Lena Alexandrova, Andrey Markin).

SRS Circle Surround encoder graciously provided by SRS Labs who were wonderful to work with. Circle Surround, SRS and SRS logo are trademarks of SRS Labs, Inc.

The Extended MIDI (XMIDI) standard was designed in collaboration with the musicians, programmers, and developers at Origin Systems in Austin, Texas. In particular, we gratefully acknowledge the expert assistance of Martin Galway, Dana Glover, Chris Roberts, Marc Schaefgen, Gary Scott Smith, Nenad Vugrinec, and Kirk Winterrowd in the evolution of the XMIDI standard. Thanks also to Ken Arnold and George ("The Fat Man") Sanger for their indispensable advice and support.

Sample digital audio files kindly supplied by Rapid Eye Entertainment. Sample MIDI file and DLS instruments kindly supplied S3, Inc.

RAD's automatic documentation system was written by Casey Muratori. Typesetting by the TeX and LaTeX typesetting systems.

Voxware Voice Chat Codecs licensed from Voxware, Inc. Copyright (C) 1996 Voxware, Inc. Voxware-enabled!

All brand and product names mentioned in this documentation are trademarks or registered trademarks of their respective companies.

Acknowledgments


Introduction

Discussion

Welcome to the Miles Sound System!

The Miles Sound System has been the standard in video game audio for more than fifteen years now. Fifteen years! It always surprises me to remember that Miles started out before Windows 3.0, before the Mac went to PowerPC, way before even the original Pentium chip - before even the original 16-bit Super NES!

And Miles remains as vital and powerful today as it was back in 1991. Our new Miles 7 is the result of a huge engineering effort - John and I worked long hours to bring you the best features for today's modern PCs and tomorrow's powerful consoles.

We now support a huge number of platforms with several more around the corner. Since we make a point of not doing simple ports, this is a lot of work, but I think you'll like the results. Just as an example, our final version of the Miles mixer for the Xbox 360 ended up 400% faster than the initial Mac-based version that we started with.

And this is what makes our products still so much fun to work on - we get to spend time on them, making them better and better with each passing year. At year fifteen, we think Miles looks better than ever.

This new version continues our progression to primarily software based audio. We still support the EAX variants on Windows, but the cool stuff is definitely happening on the software side of the pool. With Miles 7, you can do full multichannel mixing with full 3D and environmental effects including chainable DSP effects, all of which will sound exactly the same on a 5.1 PC, as a 5.1 Xbox, as a 5.1 CircleSurround encoded stream on a Mac.

The cool thing is that we were able to add all of these new features, but at the same time actually simplify the Miles API dramatically. Miles is still a pretty large SDK, but it's a lot cleaner in version 7!

This documentation will help you get a handle on all of the Miles audio APIs. We spend quite a bit of time working on our docs and hope they get you up and running fast. Please give us feedback on what worked for you and what didn't. Just as with the Miles API itself, we strive for continual improvement in our documentation as well. Your feedback is crucial in this regard!

We realize that documentation is a pain to read when you just want to get up and running quickly, so we've retooled our docs to be more focused on specific tasks and problems. Really, the only documentation that you should force yourself to read is the Overview for your game's platform, and the "FAQs and How Tos" Section.

The "FAQs and How Tos" section is the best way to learn about using Miles - there are lots of "getting started" FAQs as well as tons of hard won trouble-shooting FAQs as well.

I love these new FAQs actually - I think it's a much more effective way to learn the ins and outs of a product than poring over a reference manual - I hope you like them too!

Again, please send feedback to me as you use Miles - what confused you, what you liked, what you hated, what you'd like to see in future versions, etc. Your feedback is what keeps Miles vital, fun to use, and powerful after all these years!

Thanks for all your support,

Jeff Roberts - RAD Game Tools - E-mail.

Introduction
FAQs and How Tos


Overview for Win32: Miles on Windows XP, Vista, 2000, NT and Win9x

Discussion

Miles is most commonly used on the Win32 platform. Win32 is both wonderful and horrible (often simultaneously).

Miles is extremely easy to use and integrate under this platform. We'll discuss everything you need to know to get up and running!

Overview for Win32: Miles on Windows XP, Vista, 2000, NT and Win9x
Installation for Win32
Integrating Miles into a Win32 Build Environment
Distributing Miles with Win32 Applications
Sound under Win32
Memory management under Win32
Callbacks under Win32
Sharing the CPU under Win32
Call Logging under Win32
Miles Examples for Win32


Installation for Win32

Discussion

To install for Win32, you simply have to run the self-installer that you download from our web site.

All installation options are largely automatic, and will not require much further user input unless you would like to change anything (like the installation directory).

Next Topic (Integrating Miles into a Win32 Build Environment)

Group: Overview for Win32: Miles on Windows XP, Vista, 2000, NT and Win9x
Related Sections: Installation for DOS


Integrating Miles into a Win32 Build Environment

Discussion

To build an application that uses Miles, you must include the Miles SDK in the build process. There are four simple steps to do this:

1) Include MSS.H in your source files.

2) Link with the MSS32.LIB import library.

3) Place the MSS32.DLL file in the directory that contains your application.

4) Copy the all of the other files in the \redist directory into a subdirectory off your application directory.

And that's it - you should now be able to call the Miles functions!

Next Topic (Distributing Miles with Win32 Applications)

Previous Topic (Installation for Win32)

Group: Overview for Win32: Miles on Windows XP, Vista, 2000, NT and Win9x


Distributing Miles with Win32 Applications

Discussion

To distribute an application that uses Miles, you must include the Miles DLL (MSS32.DLL) in the same directory as your application, and you must copy all of the other files in the \redist directory to a directory accessible by your application at run-time.

If your directory path will be a Unicode path, then see the FAQ on using Unicode.

Do not place the MSS32.DLL in the Windows or the Windows System directories! The MSS32.DLL must be placed in your application directory! The Miles DLL will refuse to be loaded from a system directory.

Next Topic (Sound under Win32)

Previous Topic (Integrating Miles into a Win32 Build Environment)

Group: Overview for Win32: Miles on Windows XP, Vista, 2000, NT and Win9x
Related FAQs: How do I use a Unicode path on Windows?


Sound under Win32

Discussion

For MIDI output, the Miles Sound System can use the system MIDI hardware through the midiOut API, or it can synthesize the MIDI stream itself and feed it through the digital output system. MIDI is pretty a simple environment.

For digital audio output, however, things are a little more complicated. Miles can be configured to use either DirectSound (the preferred method) or the old waveOut audio system.

DirectSound shipped about a year after Windows 95 first shipped. It has been built into Windows since Windows 98 and Windows 2000.

DirectSound can run in native mode or emulated mode. Native mode means that DirectSound is talking directly to your sound card hardware. Emulated mode means that DirectSound is talking to old waveOut audio drivers (through an extra layer of buffering).

DirectSound in emulation mode usually works terribly. To avoid this (and to support old Win95 and old NT machines that don't have DirectSound at all), Miles can use the old waveOut sound system directly. WaveOut was the original way to play sound in Windows (it was added to Win16 way back as an add-on to Windows 3.0 - yes, audio was once considered a chargeable "add-on" by Microsoft).

WaveOut mode is nice, because it will work on pretty much any machine, but, unfortunately, it has serious latency problems. These latency issues were, in fact, the primary reason Microsoft added DirectSound.

Under waveOut, latency can rise to as high as 300 milliseconds on some older sound cards. DirectSound's latency, by comparison, rarely hits even 50 ms.

In practice, we've found that you usually don't have to worry about supporting old sound cards through waveOut, because a game's graphics usually require the latest Direct3D and/or DirectDraw anyway (so you know DirectSound will be installed).

So, by default, to deal with all of these issues, Miles tries to use DirectSound first, and then falls back to waveOut mode if DirectSound won't load or if it is running in emulation mode. So, you get DirectSound's good latency if running in native mode, and you still get waveOut's compatibility when necessary.

Be sure to review the How do I use multi-channel sound output in Miles? FAQ for an overview of the audio output configurations supported under Win32.

Next Topic (Memory management under Win32)

Previous Topic (Distributing Miles with Win32 Applications)

Group: Overview for Win32: Miles on Windows XP, Vista, 2000, NT and Win9x
Related FAQs: How do I use multi-channel sound output in Miles?


Memory management under Win32

Discussion

Under Win32, memory management is pretty easy - you can pass in any plain old memory pointer for Miles to process. If you want your memory allocations to be compatible with MacOS 9 or DOS, though, you should use the AIL_mem_alloc_lock function. If porting isn't an issue, though, just use whatever memory allocator is convenient (malloc, resource locks, whatever).

For internal memory use, Miles allocates its own memory directly from the operating system. You can intercept these memory allocation requests with the AIL_mem_use_malloc and AIL_mem_use_free functions.

Next Topic (Callbacks under Win32)

Previous Topic (Sound under Win32)

Group: Overview for Win32: Miles on Windows XP, Vista, 2000, NT and Win9x
Related Functions: AIL_mem_alloc_lock, AIL_mem_use_free, AIL_mem_use_malloc


Callbacks under Win32

Discussion

Read this section carefully if you plan to use Miles timer or other callbacks (such as an end-of-sample callback). If you don't intend to use callbacks, then this section won't apply to you.

Under Win32, callbacks are usually made to your application on a background thread. The ideal callback function is one that does nothing more than write to one or two flag variables and then immediately return back to Miles. Under Win32, other operations are allowed, but not recommended!

So, unlike MacOS 9, Wii or PS2, you can do whatever you want inside a Miles callback under Win32 - there are no OS-mandated restrictions. However, if you want to maintain easily ported code, then you should read about the callback restrictions for the other platforms you intend to support. Other platforms are much more strict than Win32 when it comes to callbacks.

In any case, you do have to take general multithread precautions in your callbacks. For example, if you use the C runtime library inside a callback, then you need to link with the multithreaded libraries. If you access your own internal data structures, then you need to make sure that the accessor functions can be called by two threads at once (unless you protect with a critical section lock).

Also remember that all global or static variables that are modified by a callback function must be declared with the volatile modifier. Otherwise, the callback function and the foreground may not be able to communicate after the compiler has performed all of its optimizing tricks.

You should also minimize the total amount of work inside a Miles callback. During a callback, Miles is suspended, so other background tasks won't run - mixing will be interrupted, for example, if you take too long.

Again, though, the best advice for callbacks is to simply post a message or set a flag that can be operated on by your foreground task. This technique works on all platforms and you'll never need to worry about the complications that multithreading can cause.

Next Topic (Sharing the CPU under Win32)

Previous Topic (Memory management under Win32)

Group: Overview for Win32: Miles on Windows XP, Vista, 2000, NT and Win9x
Related FAQs: What's the deal with callbacks - are they threads, interrupts, system timers, or what?


Sharing the CPU under Win32

Discussion

Under Win32, Miles does most of its work in a background thread. This means that Miles usually does its work without you even having to worry about it. The mixing and buffer submission to the sound hardware all happens without your intervention.

The only time you may need to specifically give Miles CPU time is if the system thread scheduler starts performing badly and the background Miles thread starves. Under the Windows 95, 98, and Me, the thread scheduler usually has the most trouble when performing disk I/O.

Miles provides several techniques to handle thread-starvation. See the AIL_get_timer_highest_delay function as well as the "My sound is skipping on Windows or MacOS X - what can I do?" FAQ for more details.

Next Topic (Call Logging under Win32)

Previous Topic (Callbacks under Win32)

Group: Overview for Win32: Miles on Windows XP, Vista, 2000, NT and Win9x
Related Functions: AIL_get_timer_highest_delay
Related FAQs: My sound is skipping on Windows or MacOS X - what can I do?


Call Logging under Win32

Discussion

Miles contains a powerful diagnostic feature that allows developers to create a timestamped list of all of their application's foreground Miles calls, along with their parameters and results. The call log will be sent to an application callback routine registered with AIL_register_trace_callback, or to a plain text file if no debug-trace callback function has been registered by the application.

To take advantage of MSS's built-in logging without the need to recompile your application, you can create an "[MSS]" section in WIN.INI, followed by a string of the form, "MSSDebug=filename.txt". During execution of all subsequent Miles calls, a timestamped API call log will be written to the specified file.

For example, to dump the API call log to a file name foo.txt, add the following lines to WIN.INI:

[MSS]
MSSDebug=foo.txt

You can also view MSS's internal function calls by adding an extra line reading, "MSSSysDebug=1".

Next Topic (Miles Examples for Win32)

Previous Topic (Sharing the CPU under Win32)

Group: Overview for Win32: Miles on Windows XP, Vista, 2000, NT and Win9x
Related Functions: AIL_register_trace_callback
Related FAQs: My application is crashing - what should I try?, Where is the Miles source code? How can I rebuild it (in debug mode)?


Miles Examples for Win32

Discussion

The Miles SDK supplies several example programs for Win32. To create these examples in an IDE-based environment, just create a new project and include the appropriate C source file (Demo.C, for example), and then add the Miles import library to the project (MSS32.LIB). The Win32 example files are found in the \src\examples directory.

For an example that uses digital sound, MIDI sound (with DLS), and CD (redbook) audio, see the Demo.C file.

The best example to follow when integrating Miles into your game is probably ExamMS.CPP. This is a simple application that illustrates many important principles, such as simultaneous use of 3D and 2D digital audio and how your game engine can maintain its audio playback state in general.

For an example that uses the Quick API, see the Quick.C file.

For an advanced example of Internet voice chat, see the MSSChat.C, MSSChtC.CPP, and MSSChtS.CPP files.

For simple, console-based examples of digital audio playback, MIDI playback (hardware based and DLS), DSP filters, and more, see the examples in the \src\examples directory.

Previous Topic (Call Logging under Win32)

Group: Overview for Win32: Miles on Windows XP, Vista, 2000, NT and Win9x


Overview for Win64: Miles on Windows 64 XP and Vista

Discussion

Miles is now available for the 64-bit version of Microsoft Windows. No changes need to be made to your Miles Win32 code to run on Win64 - everything is cleanly ported.

Miles is extremely easy to use and integrate under this platform. We'll discuss everything you need to know to get up and running!

Overview for Win64: Miles on Windows 64 XP and Vista
Installation for Win64
Integrating Miles into a Win64 Build Environment
Distributing Miles with Win64 Applications
Sound under Win64
Memory management under Win64
Callbacks under Win64
Sharing the CPU under Win64
Call Logging under Win64
Miles Examples for Win64


Installation for Win64

Discussion

To install for Win64, you simply have to run the self-installer that you download from our web site.

All installation options are largely automatic, and will not require much further user input unless you would like to change anything (like the installation directory).

Next Topic (Integrating Miles into a Win64 Build Environment)

Group: Overview for Win64: Miles on Windows 64 XP and Vista


Integrating Miles into a Win64 Build Environment

Discussion

To build an application that uses Miles, you must include the Miles SDK in the build process. There are four simple steps to do this:

1) Include MSS.H in your source files.

2) Link with the MSS64.LIB import library.

3) Place the MSS64.DLL file in the directory that contains your application.

4) Copy the all of the other files in the \redist64 directory into a subdirectory off your application directory.

And that's it - you should now be able to call the Miles functions!

Next Topic (Distributing Miles with Win64 Applications)

Previous Topic (Installation for Win64)

Group: Overview for Win64: Miles on Windows 64 XP and Vista


Distributing Miles with Win64 Applications

Discussion

To distribute an application that uses Miles, you must include the Miles DLL (MSS64.DLL) in the same directory as your application, and you must copy all of the other files in the \redist directory to a directory accessible by your application at run-time.

If your directory path will be a Unicode path, then see the FAQ on using Unicode.

Do not place the MSS64.DLL in the Windows or the Windows System directories! The MSS64.DLL must be placed in your application directory! The Miles DLL will refuse to be loaded from a system directory.

Next Topic (Sound under Win64)

Previous Topic (Integrating Miles into a Win64 Build Environment)

Group: Overview for Win64: Miles on Windows 64 XP and Vista
Related FAQs: How do I use a Unicode path on Windows?


Sound under Win64

Discussion

For MIDI output, the Miles Sound System can use the system MIDI hardware through the midiOut API, or it can synthesize the MIDI stream itself and feed it through the digital output system. MIDI is pretty a simple environment.

For digital audio output, however, things are a little more complicated. Miles can be configured to use either DirectSound (the preferred method) or the old waveOut audio system. On Win64, all of the sound drivers use DirectSound, so waveOut should never be necessary.

Be sure to review the How do I use multi-channel sound output in Miles? FAQ for an overview of the audio output configurations supported under Win64.

Next Topic (Memory management under Win64)

Previous Topic (Distributing Miles with Win64 Applications)

Group: Overview for Win64: Miles on Windows 64 XP and Vista
Related FAQs: How do I use multi-channel sound output in Miles?


Memory management under Win64

Discussion

Under Win64, memory management is pretty easy - you can pass in any plain old memory pointer for Miles to process. If you want your memory allocations to be compatible with MacOS 9 or DOS, though, you should use the AIL_mem_alloc_lock function. If porting isn't an issue, though, just use whatever memory allocator is convenient (malloc, resource locks, whatever).

For internal memory use, Miles allocates its own memory directly from the operating system. You can intercept these memory allocation requests with the AIL_mem_use_malloc and AIL_mem_use_free functions.

Next Topic (Callbacks under Win64)

Previous Topic (Sound under Win64)

Group: Overview for Win64: Miles on Windows 64 XP and Vista
Related Functions: AIL_mem_alloc_lock, AIL_mem_use_free, AIL_mem_use_malloc


Callbacks under Win64

Discussion

Read this section carefully if you plan to use Miles timer or other callbacks (such as an end-of-sample callback). If you don't intend to use callbacks, then this section won't apply to you.

Under Win64, callbacks are usually made to your application on a background thread. The ideal callback function is one that does nothing more than write to one or two flag variables and then immediately return back to Miles. Under Win64, other operations are allowed, but not recommended!

So, unlike MacOS 9, Wii or PS2, you can do whatever you want inside a Miles callback under Win32 - there are no OS-mandated restrictions. However, if you want to maintain easily ported code, then you should read about the callback restrictions for the other platforms you intend to support. Other platforms are much more strict than Win64 when it comes to callbacks.

In any case, you do have to take general multithread precautions in your callbacks. For example, if you use the C runtime library inside a callback, then you need to link with the multithreaded libraries. If you access your own internal data structures, then you need to make sure that the accessor functions can be called by two threads at once (unless you protect with a critical section lock).

Also remember that all global or static variables that are modified by a callback function must be declared with the volatile modifier. Otherwise, the callback function and the foreground may not be able to communicate after the compiler has performed all of its optimizing tricks.

You should also minimize the total amount of work inside a Miles callback. During a callback, Miles is suspended, so other background tasks won't run - mixing will be interrupted, for example, if you take too long.

Again, though, the best advice for callbacks is to simply post a message or set a flag that can be operated on by your foreground task. This technique works on all platforms and you'll never need to worry about the complications that multithreading can cause.

Next Topic (Sharing the CPU under Win64)

Previous Topic (Memory management under Win64)

Group: Overview for Win64: Miles on Windows 64 XP and Vista
Related FAQs: What's the deal with callbacks - are they threads, interrupts, system timers, or what?


Sharing the CPU under Win64

Discussion

Under Win64, Miles does most of its work in a background thread. This means that Miles usually does its work without you even having to worry about it. The mixing and buffer submission to the sound hardware all happens without your intervention.

The only time you may need to specifically give Miles CPU time is if the system thread scheduler starts performing badly and the background Miles thread starves.

Miles provides several techniques to handle thread-starvation. See the AIL_get_timer_highest_delay function as well as the "My sound is skipping on Windows or MacOS X - what can I do?" FAQ for more details.

Next Topic (Call Logging under Win64)

Previous Topic (Callbacks under Win64)

Group: Overview for Win64: Miles on Windows 64 XP and Vista
Related Functions: AIL_get_timer_highest_delay
Related FAQs: My sound is skipping on Windows or MacOS X - what can I do?


Call Logging under Win64

Discussion

Miles contains a powerful diagnostic feature that allows developers to create a timestamped list of all of their application's foreground Miles calls, along with their parameters and results. The call log will be sent to an application callback routine registered with AIL_register_trace_callback, or to a plain text file if no debug-trace callback function has been registered by the application.

To take advantage of MSS's built-in logging without the need to recompile your application, you can create an "[MSS]" section in WIN.INI, followed by a string of the form, "MSSDebug=filename.txt". During execution of all subsequent Miles calls, a timestamped API call log will be written to the specified file.

For example, to dump the API call log to a file name foo.txt, add the following lines to WIN.INI:

[MSS]
MSSDebug=foo.txt

You can also view MSS's internal function calls by adding an extra line reading, "MSSSysDebug=1".

Next Topic (Miles Examples for Win64)

Previous Topic (Sharing the CPU under Win64)

Group: Overview for Win64: Miles on Windows 64 XP and Vista
Related Functions: AIL_register_trace_callback
Related FAQs: My application is crashing - what should I try?, Where is the Miles source code? How can I rebuild it (in debug mode)?


Miles Examples for Win64

Discussion

The Miles SDK supplies several example programs for Win64. To create these examples in an IDE-based environment, just create a new project and include the appropriate C source file (Demo.C, for example), and then add the Miles import library to the project (MSS64.LIB). The Win64 example files are found in the \src\examples directory.

For an example that uses digital sound, MIDI sound (with DLS), and CD (redbook) audio, see the Demo.C file.

The best example to follow when integrating Miles into your game is probably ExamMS.CPP. This is a simple application that illustrates many important principles, such as simultaneous use of 3D and 2D digital audio and how your game engine can maintain its audio playback state in general.

For an example that uses the Quick API, see the Quick.C file.

For simple, console-based examples of digital audio playback, MIDI playback (hardware based and DLS), DSP filters, and more, see the examples in the \src\examples directory.

Previous Topic (Call Logging under Win64)

Group: Overview for Win64: Miles on Windows 64 XP and Vista


Overview for Nintendo Wii

Discussion

As with the other console versions, Miles is extremely easy to use and integrate on the Wii.

The Wii CPU is really friendly to optimizations - we tweaked a lot of the PPC assembly to get things running super-fast on this machine.

Overview for Nintendo Wii
Installation for Nintendo Wii
Integrating Miles into a Nintendo Wii Build Environment
Distributing Miles with Nintendo Wii Applications
Sound under Nintendo Wii
Memory management under Nintendo Wii
Callbacks under Nintendo Wii
Call Logging under Nintendo
Resource Usage on the Nintendo
MSS Example for the Nintendo Wii


Installation for Nintendo Wii

Discussion

To install for Wii, you simply have to run the self-installer that you download from our web site.

All installation options are largely automatic, and will not require much further user input unless you would like to change anything (like the installation directory).

Next Topic (Integrating Miles into a Nintendo Wii Build Environment)

Group: Overview for Nintendo Wii


Integrating Miles into a Nintendo Wii Build Environment

Discussion

To build an application that uses Miles, you must include the Miles SDK in the build process. Only a few simple steps are required:

1) Include MSS.H in all of the source files that need to call Miles functions.

2) Link with the MSSWii.A library.

3) If you are using MP3 data, link with the MP3Wii.A library. If you are using Ogg Vorbis data, link with the OGGWii.A library.

4) If you're using Dolby Surround (which is a great fast multispeaker solution for the Wii), link with mssdolby.a.

4) If you're using SRS CircleSurround (which is a great sounding, but slightly slower multispeaker solution for the Wii), link with msssrs.a.

5) If you'd like to use per-sample DSP filters, link with FLTWii.A.

And that's it - you should now be able to call the Miles functions! (Don't forget the Register_RIB calls needed for the Dolby, SRS, and DSP filter options -- see MilesWii.cpp for an example.)

Next Topic (Distributing Miles with Nintendo Wii Applications)

Previous Topic (Installation for Nintendo Wii)

Group: Overview for Nintendo Wii
Related Functions: Register_RIB


Distributing Miles with Nintendo Wii Applications

Discussion

Miles is supplied as a set of static libraries on the Wii, so once you have linked your application, you don't need to distribute any other files.

Next Topic (Sound under Nintendo Wii)

Previous Topic (Integrating Miles into a Nintendo Wii Build Environment)

Group: Overview for Nintendo Wii


Sound under Nintendo Wii

Discussion

The Miles Sound System on Wii supports the same uncompressed PCM, IMA ADPCM, MP3, and Ogg Vorbis digital sound formats that we support on our other platforms. ADPCM, MP3 and Ogg Vorbis are not natively supported by the Wii, but Miles makes the decompression and streaming to the sound hardware seamless. In particular, the ADPCM and MP3 decompressors are very well-optimized for the Wii.

Miles on the Wii also offers fully-integrated 2D and 3D sound. SRS CircleSurround and Dolby Surround offer easy ways to add multi-speaker audio to your title.

Miles uses its built-in DLS synthesizer for all MIDI playback. This has the advantage of allowing you to author custom DLS instrument sets to optimize memory use.

Next Topic (Memory management under Nintendo Wii)

Previous Topic (Distributing Miles with Nintendo Wii Applications)

Group: Overview for Nintendo Wii


Memory management under Nintendo Wii

Discussion

By default on the Wii, Miles simply calls the OSAlloc/OSFree system functions.

You can, of course, intercept these memory allocation requests with the AIL_mem_use_malloc and AIL_mem_use_free functions.

Next Topic (Callbacks under Nintendo Wii)

Previous Topic (Sound under Nintendo Wii)

Group: Overview for Nintendo Wii
Related Functions: AIL_mem_use_free, AIL_mem_use_malloc


Callbacks under Nintendo Wii

Discussion

Read this section carefully if you plan to use Miles timer or other callbacks (such as an end-of-sample callback). If you don't intend to use callbacks, then this section won't apply to you.

On the Wii, callbacks are usually made to your application from an alarm interrupt handler. The ideal callback function is one that does nothing more than write to one or two flag variables and then immediately return back to Miles. At interrupt time on the Wii, certain operations are allowed but not recommended -- while other operations are forbidden altogether. The Nintendo documentation is the final authority here.

In any event, if you want to maintain portable code, you should read about the callback restrictions for the other platforms you intend to support.

Remember that all global or static variables that are modified by a callback function must be declared with the volatile modifier. Otherwise, the callback function and the foreground may not be able to communicate after the compiler has performed all of its optimizing tricks.

You should also minimize the total amount of work inside a Miles callback. During a callback, Miles is suspended, so other background tasks won't run - mixing will be interrupted, for example, if you take too long.

Again the best advice for callbacks is to simply post a message or set a flag that can be operated on by your foreground task. This technique works on all platforms and you'll never need to worry about the complications that multithreading or interrupts can cause.

Next Topic (Call Logging under Nintendo)

Previous Topic (Memory management under Nintendo Wii)

Group: Overview for Nintendo Wii
Related FAQs: What's the deal with callbacks - are they threads, interrupts, system timers, or what?


Call Logging under Nintendo

Discussion

Miles contains a powerful diagnostic feature that allows developers to create a list of all of their application's foreground Miles calls, along with their parameters and results. The call log will be sent to an application callback routine registered with AIL_register_trace_callback, or to the Wii debugging console via OSReport if no debug-trace callback function has been registered by the application.

To take advantage of MSS's built-in logging without recompiling your application, you can create a text file called mss_debug_log.txt in the DvdRoot directory of your ODEM emulator. If this file exists, then during execution of all subsequent Miles calls, a timestamped API call log will be passed to OSReport.

Next Topic (Resource Usage on the Nintendo)

Previous Topic (Callbacks under Nintendo Wii)

Group: Overview for Nintendo Wii
Related Functions: AIL_register_trace_callback
Related FAQs: My application is crashing - what should I try?, Where is the Miles source code? How can I rebuild it (in debug mode)?


Resource Usage on the Nintendo

Discussion

We have tried very hard to be as low-impact on the Wii hardware as possible.

1) We use one alarm interrupt callback for timer services (sound mixing takes place in one of these, for example).

2) We use two AX sound voices for stero playback, and one voice for mono.

3) We do all IO with DVDReadAsync. We handle all misaligned addresses, offsets and lengths transparently in our IO functions. That means if you override the IO functions, then you have to handle them too.

We've worked hard to make MSS as easy to drop in as any of our other platforms - unlike a lot of other middleware, we think you'll be pleasantly surprised at how little work you'll have to do.

Next Topic (MSS Example for the Nintendo Wii)

Previous Topic (Call Logging under Nintendo)

Group: Overview for Nintendo Wii


MSS Example for the Nintendo Wii

Discussion

The MSS SDK supplies MilesWii.CPP, an example program for the Wii. To build this example with CodeWarrior, just create a new project and include the MilesWii.CPP source file. Then add any necessary MSS libraries MSSWii.A, FLTWii.A, MP3Wii.A, OGGWii.A, MSSSRS.A, and MSSDOLBY.A to the project. (Only the MSSWii.A library is mandatory.)

We also ship the Miles for Wii example pre-built, so that you can try it immediately. To use it, simply launch the example image on the Wii with ndrun. Make sure to your DvdRoot emulation drive has the media directory in it.

Previous Topic (Resource Usage on the Nintendo)

Group: Overview for Nintendo Wii


Overview for Sony PlayStation 3

Discussion

Like the other next-gen systems, the PS3 is a powerful machine and includes all of the conveniences of modern operating systems. A lot of work has gone into making the PS3 version of Miles low-impact and easy to use.

Overview for Sony PlayStation 3
Installation for PlayStation 3
Integrating Miles into a PlayStation 3 Build Environment
Distributing Miles with PlayStation 3 Applications
Sound under Playstation 3
Memory management under PlayStation 3
Callbacks on Playstation 3
Call Logging under PlayStation 3
Resource Usage on the Playstation 3
MSS Example for the PlayStation 3


Installation for PlayStation 3

Discussion

To install for PlayStation 3, you simply have to run the self-installer that you download from our web site.

All installation options are largely automatic, and will not require much further user input unless you would like to change anything (like the installation directory).

Next Topic (Integrating Miles into a PlayStation 3 Build Environment)

Group: Overview for Sony PlayStation 3


Integrating Miles into a PlayStation 3 Build Environment

Discussion

To build an application that uses Miles, you must include the Miles SDK in the build process. Only a few simple steps are required:

1) Include MSS.H in all of the source files that need to call Miles functions.

2) Link with the MSSPS3.A library.

3) If you are using MP3 data, link with the MP3PS3.A library. If you are using Ogg Vorbis data, link with the OGGPS3.A library.

4) If you'd like to use per-sample DSP filters, link with FLTPS3.A.

And that's it - you should now be able to call the Miles functions! (Don't forget the Register_RIB calls needed for the MP3, Ogg and DSP filter options -- see MilesPS3.cpp for an example.)

Next Topic (Distributing Miles with PlayStation 3 Applications)

Previous Topic (Installation for PlayStation 3)

Group: Overview for Sony PlayStation 3
Related Functions: Register_RIB


Distributing Miles with PlayStation 3 Applications

Discussion

Miles is supplied as a set of static libraries on the PS3, so once you have linked your application, you don't need to distribute any other files.

Next Topic (Sound under Playstation 3)

Previous Topic (Integrating Miles into a PlayStation 3 Build Environment)

Group: Overview for Sony PlayStation 3


Sound under Playstation 3

Discussion

The Miles Sound System on PS3 supports the same uncompressed PCM, IMA ADPCM, MP3, and Ogg Vorbis digital sound formats that we support on our other platforms.

Miles talks to the libAudio library for its sound output. It does all mixing internally (on the PPU now, but on an SPU in an upcoming version). Miles has full multi-channel output support on the PS3 (up to 7.1), but it's a little tricky to get this working on the hardware side. You need the exact right kind of amplifier combined with the right HDMI TV, with the right system configuration. We expect this to get better in the future.

To configure the hardware correctly on the PS3-side, you should first run the system HUD to select the output you'd like (this is what your end-users do). Then, at runtime, you query the system to find out what mode the user requested, and then call cellAudioOutConfigure to actually put the hardware into that mode. Finally, you call cellAudioInit to start libAudio, and then start up Miles normally! See the MilesPS3.cpp file for an example of all of this.

In the meantime, you should run the system settings utility (we use the dtpon.exe utility) to set up the hardware, and then tell Miles to run in 6 or 8 channel mode. In some cases, you will still only get stereo output, but the hardware will eventually do all of this correctly. Miles on PS3 supports stereo, 5.1 discrete and 7.1 discrete output.

Miles uses its built-in DLS synthesizer for all MIDI playback. This has the advantage of allowing you to author custom DLS instrument sets to optimize memory use.

Next Topic (Memory management under PlayStation 3)

Previous Topic (Distributing Miles with PlayStation 3 Applications)

Group: Overview for Sony PlayStation 3


Memory management under PlayStation 3

Discussion

By default on the PS3, Miles simply calls the malloc/free C runtime library functions.

You can, of course, intercept these memory allocation requests with the AIL_mem_use_malloc and AIL_mem_use_free functions.

Next Topic (Callbacks on Playstation 3)

Previous Topic (Sound under Playstation 3)

Group: Overview for Sony PlayStation 3
Related Functions: AIL_mem_use_free, AIL_mem_use_malloc


Callbacks on Playstation 3

Discussion

Read this section carefully if you plan to use Miles timer or other callbacks (such as an end-of-sample callback). If you don't intend to use callbacks, then this section won't apply to you.

On the PS3, callbacks are usually made to your application on a background thread. The ideal callback function is one that does nothing more than write to one or two flag variables and then immediately return back to Miles.

So, unlike MacOS 9, Wii or PS2, you can do most of what you want inside a Miles callback on the PS3 - there are few OS-mandated restrictions. However, if you want to maintain easily ported code, then you should read about the callback restrictions for the other platforms you intend to support. Other platforms are much more strict than the PS3 when it comes to callbacks.

In any case, you do have to take general multithread precautions in your callbacks. For example, if you use the C runtime library inside a callback, then you need to link with the multithreaded libraries. If you access your own internal data structures, then you need to make sure that the accessor functions can be called by two threads at once (unless you protect with a critical section lock).

Also remember that all global or static variables that are modified by a callback function must be declared with the volatile modifier. Otherwise, the callback function and the foreground may not be able to communicate after the compiler has performed all of its optimizing tricks.

You should also minimize the total amount of work inside a Miles callback. During a callback, Miles is suspended, so other background tasks won't run - mixing will be interrupted, for example, if you take too long.

Again, though, the best advice for callbacks is to simply post a message or set a flag that can be operated on by your foreground task. This technique works on all platforms and you'll never need to worry about the complications that multithreading can cause.

Next Topic (Call Logging under PlayStation 3)

Previous Topic (Memory management under PlayStation 3)

Group: Overview for Sony PlayStation 3
Related FAQs: What's the deal with callbacks - are they threads, interrupts, system timers, or what?


Call Logging under PlayStation 3

Discussion

Miles contains a powerful diagnostic feature that allows developers to create a timestamped list of all of their application's foreground Miles calls, along with their parameters and results. The call log will be sent to an application callback routine registered with AIL_register_trace_callback, or to a plain text file if no debug-trace callback function has been registered by the application.

To take advantage of MSS's built-in logging without recompiling your application, just create a text file called /dev_hdd0/mss_debug_log.txt on the internal PS3 hard drive. If this file exists, then, during execution of all subsequent Miles calls, a timestamped API call log will be written to the file.

Next Topic (Resource Usage on the Playstation 3)

Previous Topic (Callbacks on Playstation 3)

Group: Overview for Sony PlayStation 3
Related Functions: AIL_register_trace_callback
Related FAQs: My application is crashing - what should I try?, Where is the Miles source code? How can I rebuild it (in debug mode)?


Resource Usage on the Playstation 3

Discussion

Miles is very low impact on the PS3. Currently, we do all work on the PPU on a background thread. We use about 10% of the PPU to play 32 samples right now.

However, in an upcoming version, we will move most of that down to the SPU. We expect mixing, ADPCM decompression, MP3 decompression and DSP filtering to run on the SPU.

For our sound output, we use one of the four output ports that libAudio supports so we should run along other middleware just fine.

Next Topic (MSS Example for the PlayStation 3)

Previous Topic (Call Logging under PlayStation 3)

Group: Overview for Sony PlayStation 3


MSS Example for the PlayStation 3

Discussion

The MSS SDK supplies MilesPS3.CPP, an example program for the PS3. To build this example with SN Systems or CodeWarrior, just create a new project and include the appropriate .CPP source file (demo.cpp). Then add any necessary MSS libraries MSSPS3.A, FLTPS3.A, MP3PS3.A, and OGGPS3.A to the project. (Only the MSSPS3.A library is mandatory; you can edit the input format types to remove the other libraries).

We also ship the Miles for PS3 example pre-built, so that you can try it immediately. To use it, simply launch the example image on the PS3 with the files in the media directory copied into the HOST_ROOT/media/miles directory.

Previous Topic (Resource Usage on the Playstation 3)

Group: Overview for Sony PlayStation 3


Overview for Sony PlayStation 2

Discussion

As with the other console versions, Miles is extremely easy to use and integrate on the PS2, bringing features like MP3 playback to the platform that were formerly too performance-intensive to be practical.

The Playstation 2 is one of the most painstakingly optimized of all of the Miles platforms. We have spent a lot getting things fast for this platform.

Overview for Sony PlayStation 2
Installation for PlayStation 2
Integrating Miles into a PlayStation 2 Build Environment
Distributing Miles with PlayStation 2 Applications
Sound under Playstation 2
Memory management under PlayStation 2
Callbacks under PlayStation 2
Call Logging under PlayStation 2
Resource Usage on the Playstation 2
MSS Example for the PlayStation 2


Installation for PlayStation 2

Discussion

To install for PlayStation 2, you simply have to run the self-installer that you download from our web site.

All installation options are largely automatic, and will not require much further user input unless you would like to change anything (like the installation directory).

Next Topic (Integrating Miles into a PlayStation 2 Build Environment)

Group: Overview for Sony PlayStation 2


Integrating Miles into a PlayStation 2 Build Environment

Discussion

To build an application that uses Miles, you must include the Miles SDK in the build process. Only a few simple steps are required:

1) Include MSS.H in all of the source files that need to call Miles functions.

2) Link with the MSSPS2.A library.

3) If you are using MP3 data, link with the MP3PS2.A library. If you are using Ogg Vorbis data, link with the OGGPS2.A library.

4) If you're using Dolby Surround (which is a usable low-end multispeaker solution on the PS2), link with mssdolby.a.

5) If you're using DTS, which is by far the preferred multispeaker solution on the PS2, you will need to link with both mssdts.a and the DTS-supplied realtime encoder library libidtsenc.a. This library module will need to be obtained directly from DTS.

6) If you'd like to use per-sample DSP filters, link with FLTPS2.A.

7) Include RAD_IOP.H in the source file that initializes Miles.

And that's it - you should now be able to call the Miles functions! (Don't forget the Register_RIB calls needed for the Dolby, DTS, and DSP filter options -- see MilesPS2.cpp for an example.)

Next Topic (Distributing Miles with PlayStation 2 Applications)

Previous Topic (Installation for PlayStation 2)

Group: Overview for Sony PlayStation 2
Related Functions: Register_RIB


Distributing Miles with PlayStation 2 Applications

Discussion

Miles is supplied as a set of static libraries on the PS2, so once you have linked your application, you don't need to distribute any other files.

Next Topic (Sound under Playstation 2)

Previous Topic (Integrating Miles into a PlayStation 2 Build Environment)

Group: Overview for Sony PlayStation 2


Sound under Playstation 2

Discussion

The Miles Sound System on PS2 supports the same uncompressed PCM, IMA ADPCM, MP3, and Ogg Vorbis digital sound formats that we support on our other platforms. ADPCM, MP3 and Ogg Vorbis are not natively supported by the PS2, but Miles makes the decompression and streaming to the sound hardware seamless. In particular, the ADPCM and MP3 decompressors are very well-optimized for the PS2.

Miles on the PS2 also offers fully-integrated 2D and 3D sound. DTS and Dolby Surround offer three easy ways to add multi-speaker audio to your title.

Miles uses its built-in DLS synthesizer for all MIDI playback. This has the advantage of allowing you to author custom DLS instrument sets to optimize memory use.

Next Topic (Memory management under PlayStation 2)

Previous Topic (Distributing Miles with PlayStation 2 Applications)

Group: Overview for Sony PlayStation 2


Memory management under PlayStation 2

Discussion

By default on the PS2, Miles simply calls the malloc/free C runtime library functions.

You can, of course, intercept these memory allocation requests with the AIL_mem_use_malloc and AIL_mem_use_free functions.

Miles can also use IOP and SPU RAM for storing audio data. To do this, first you load the sound data into IOP or SPU memory (the RAD_IOPQueueAsyncReadAtTop function does this), and then you use the Miles streaming audio functions (such as AIL_open_stream) to play it.

Next Topic (Callbacks under PlayStation 2)

Previous Topic (Sound under Playstation 2)

Group: Overview for Sony PlayStation 2
Related Functions: AIL_mem_use_free, AIL_mem_use_malloc, AIL_open_stream, RAD_IOPQueueAsyncReadAtTop


Callbacks under PlayStation 2

Discussion

Read this section carefully if you plan to use Miles timer or other callbacks (such as an end-of-sample callback). If you don't intend to use callbacks, then this section won't apply to you.

On the PS2, callbacks are usually made to your application from an IOP interrupt handler. The ideal callback function is one that does nothing more than write to one or two flag variables and then immediately return back to Miles. At interrupt time on the PS2, certain operations are allowed but not recommended -- while other operations are forbidden altogether. The Sony documentation is the final authority here. (However, because Miles saves and restores the state of the floating-point unit at interrupt time, you can perform floating-point operations within Miles callback functions without difficulty.)

In any event, if you want to maintain portable code, you should read about the callback restrictions for the other platforms you intend to support.

Remember that all global or static variables that are modified by a callback function must be declared with the volatile modifier. Otherwise, the callback function and the foreground may not be able to communicate after the compiler has performed all of its optimizing tricks.

You should also minimize the total amount of work inside a Miles callback. During a callback, Miles is suspended, so other background tasks won't run - mixing will be interrupted, for example, if you take too long.

Again the best advice for callbacks is to simply post a message or set a flag that can be operated on by your foreground task. This technique works on all platforms and you'll never need to worry about the complications that multithreading or interrupts can cause.

Next Topic (Call Logging under PlayStation 2)

Previous Topic (Memory management under PlayStation 2)

Group: Overview for Sony PlayStation 2
Related FAQs: What's the deal with callbacks - are they threads, interrupts, system timers, or what?


Call Logging under PlayStation 2

Discussion

Miles contains a powerful diagnostic feature that allows developers to create a list of all of their application's foreground Miles calls, along with their parameters and results. The call log will be sent to an application callback routine registered with AIL_register_trace_callback, or to the PS2 debugging console via scePrintf if no debug-trace callback function has been registered by the application.

To take advantage of MSS's built-in logging without recompiling your application, you can create a text file called mss_debug_log.txt in the root directory of your PS2 development host's hard drive (d:\ from a PC). If this file exists, then during execution of all subsequent Miles calls, a timestamped API call log will be passed to scePrintf.

Next Topic (Resource Usage on the Playstation 2)

Previous Topic (Callbacks under PlayStation 2)

Group: Overview for Sony PlayStation 2
Related Functions: AIL_register_trace_callback
Related FAQs: My application is crashing - what should I try?, Where is the Miles source code? How can I rebuild it (in debug mode)?


Resource Usage on the Playstation 2

Discussion

We have tried very hard to be as low-impact on the PS2 hardware as possible, since resource contention is one of the trickiest bits of PS2 programming. We didn't want MSS to make that situation worse.

1) We use EE (of course), but no threads. We run on the same thread that you call us on. We do have interrupts happening in the background to service the I/O coming in from the IOP, but this is all low-impact stuff unless more CPU-intensive features like MP3, Ogg Vorbis, DLS, or CircleSurround processing are enabled.

2) Our MP3 decoder and DTS encoder can use scratchpad RAM for improved performance if the AIL_set_scratchpad_policy function is called with MSS_USE_AND_SAVE or MSS_USE_WITHOUT_SAVING. For MP3 decoding, the advantage amounts to about 15% of the total Miles time slice (which is already small), but if you're using real-time DTS encoding, then the scratchpad is definitely worth enabling. By default, we do not use the scratchpad.

3) We save and restore the floating-point unit's contents and state during interrupt processing, including any MSS timers registered by the application. Although we seldom recommend calling runtime library functions from within callback functions, this does mean you can disregard Sony's prohibitions against using certain SCE runtime functions at interrupt time.

4) We use the IOP to handle all I/O in the background. The EE tells the IOP to start reading, and whenever the IOP has a packet of data ready (usually 4K), it DMAs it over to the EE, triggers an EE interrupt, and then the EE tells the IOP the next piece of data to read. We use the sceCdRead function for CD or DVD reads, and the simple C runtime functions (open, lseek, read, and close) to read from the host or the hard drive.

5) The IOP IRX that we use for our IOP component is built into the MSS library and loaded and unloaded automatically as necessary. The IOP memory that we use for buffering is allocated by your game and passed into us (we do no direct allocation of IOP memory).

6) We use the PCM channel on one of the two SPU sound chips for all audio output (we mix everything down to one hardware output channel). Other than this PCM sound channel, we don't touch any of the rest of the sound functionality. This means you can use any API (like Multistream) to control the other 48 ADPCM voices or even the other PCM channel. We expect that we would work with any sound output middleware, assuming they don't pound on the same hardware voice that you told us to use. (Be sure to review the discussion of the RAD_IOP layer in the PS2 support-services section if you need MSS to coexist with other IOP-based resources.)

7) We use one SIF command handler to communicate between the EE and IOP. This simple API is rarely used, so the chance of conflict is low. You can specify which command handler to use, if you actually are using this API.

8) The DTS encoder heavily utilizes VU0 (Vector Unit 0) in macro mode. Registers VF01 through VF31 and the ACC register, as well as the MAC and Status flags, are all used by the DTS encoder at interrupt time. MSS saves and restores these registers, so your application should not normally be affected.

9) If any VU0 code is executing in micro mode when an MSS mixer service interrupt occurs, the DTS encoder will stall until the micro mode routine has finished executing. Any code or data in local VU0 memory is not affected by the encoder.

We've worked hard to make MSS as easy to drop in as any of our other platforms - unlike a lot of other middleware, we think you'll be pleasantly surprised at how little work you'll have to do.

Next Topic (MSS Example for the PlayStation 2)

Previous Topic (Call Logging under PlayStation 2)

Group: Overview for Sony PlayStation 2
Related Functions: AIL_set_scratchpad_policy


MSS Example for the PlayStation 2

Discussion

The MSS SDK supplies MilesPS2.CPP, an example program for the PS2. To build this example with SN Systems or CodeWarrior, just create a new project and include the appropriate MilesPS2.CPP source file. Then add any necessary MSS libraries MSSPS2.A, FLTPS2.A, MP3PS2.A, OGGPS2.A, MSSDTS.A, and MSSDOLBY.A to the project. (Only the MSSPS2.A library is mandatory; you can edit the #defines near the top of MilesPS2.CPP to take advantage of the optional Miles features supported by the DTS and Dolby Surround libraries.)

We also ship the Miles for PS2 example pre-built, so that you can try it immediately. To use it, simply launch the example image on the PS2 with two parameters on the command line. The first command line parameter should be a host0 specific path to the directory containing the IOP runtime modules (the *.IRX files) - this is usually "c:/usr/local/sce/iop/modules". The second command line parameter should be the path to the directory containing the Miles PS2 example media files - usually "host0:c:/MilesPS2/examples/media".

Note that the first parameter shouldn't use "host0:" on the front, because it always loads the IRX files from host0. The second parameter does need a device first (like host0:, or cd0:, etc.), since it can play them off any device for testing purposes.

Previous Topic (Resource Usage on the Playstation 2)

Group: Overview for Sony PlayStation 2


Overview for Microsoft Xbox

Discussion

Miles has always supported Microsoft's original Xbox console. The Xbox is really great to develop for - good tools plus robust hardware is a nice combination.

The Xbox version of Miles is actually the most sophisticated version - it is highly optimized and supports the hardware intimately.

Miles is extremely easy to use and integrate under this platform. We'll discuss everything you need to know to get up and running!

Overview for Microsoft Xbox
Installation for Xbox
Integrating Miles into a Xbox Build Environment
Distributing Miles with Xbox Applications
Sound under Xbox
Memory management under Xbox
Callbacks under Xbox
Sharing the CPU under Xbox
Call Logging under Xbox
Miles Example for Xbox
How do I use multi-channel sound output in Miles?


Installation for Xbox

Discussion

To install for Xbox, you simply have to run the self-installer that you download from our web site.

All installation options are largely automatic, and will not require much further user input unless you would like to change anything (like the installation directory).

Next Topic (Integrating Miles into a Xbox Build Environment)

Group: Overview for Microsoft Xbox


Integrating Miles into a Xbox Build Environment

Discussion

To build an application that uses Miles, you must include the Miles SDK in the build process. There are four simple steps to do this:

1) Include MSS.H in your source files.

2) Link with the MSSXbox.LIB or MSSXbox.LTCG.LIB libraries. Using the LTCG library will result in slightly better performance and memory use, but it takes longer to link and Edit and Continue will no longer work.

3) If you are using MP3 data, link with the MP3xbox.LIB or MP3xbox.LTCG.LIB libraries. If you are using Ogg Vorbis data, link with the Oggxbox.LIB or Oggxbox.LTCG.LIB libraries.

4) If you are the software DSP filters, link with the fltxbox.LIB or fltxbox.LTCG.LIB libraries.

And that's it - you should now be able to call the Miles functions!

Next Topic (Distributing Miles with Xbox Applications)

Previous Topic (Installation for Xbox)

Group: Overview for Microsoft Xbox


Distributing Miles with Xbox Applications

Discussion

Miles is supplied as a static library on the Xbox, so once you have linked your XBE, you don't need to distribute any other files.

Next Topic (Sound under Xbox)

Previous Topic (Integrating Miles into a Xbox Build Environment)

Group: Overview for Microsoft Xbox


Sound under Xbox

Discussion

For digital audio output, Miles for Xbox uses the DirectSound system library. Miles is carefully designed to use the powerful built-in hardware on the Xbox to its fullest. You can play hundreds of digital samples at once with no CPU hit at all!

The Miles Sound System on Xbox supports uncompressed, IMA ADPCM, MP3, Ogg Vorbis, and Xbox ADPCM digital sound. IMA, MP3, and Ogg Vorbis are not natively supported by the Xbox, but Miles makes the decompression and streaming to the sound hardware seamless - they just take a little more CPU. In particular, our IMA ADPCM and MP3 decompressors are optimized for the Xbox - MP3 decompression is almost three times faster than WMA compression, for example. Even better, Xbox ADPCM takes no CPU at all to decompress!

Miles on the Xbox also has integrated 2D and 3D sound subsystems. (Note that 3D positioning support works even if you don't open the Xbox driver with the AIL_OPEN_DIGITAL_NEED_HW_3D flag. It's faster if you use hardware 3D positioning, but a driver opened with AIL_OPEN_DIGITAL_NEED_HW_3D makes fewer voices available to the application and won't support certain features like stereo samples and streams.)

The Xbox also supports full 5.1 discrete audio. You can set the volume levels of the 5.1 individual channels with the AIL_set_sample_51_volume_pan or AIL_set_sample_51_volume_levels functions.

The Xbox doesn't have dedicated MIDI hardware, so Miles uses its built-in DLS synthesizer for all MIDI playback. This has the added advantage of allowing you to author custom DLS instrument sets to optimize memory use.

And that's pretty much it - Miles is a piece of cake to use on the Xbox.

Next Topic (Memory management under Xbox)

Previous Topic (Distributing Miles with Xbox Applications)

Group: Overview for Microsoft Xbox
Related Functions: AIL_set_sample_51_volume_levels, AIL_set_sample_51_volume_pan


Memory management under Xbox

Discussion

By default on the Xbox, Miles simply requests memory directly from the OS.

You can, of course, intercept these memory allocation requests with the AIL_mem_use_malloc and AIL_mem_use_free functions.

Next Topic (Callbacks under Xbox)

Previous Topic (Sound under Xbox)

Group: Overview for Microsoft Xbox
Related Functions: AIL_mem_use_free, AIL_mem_use_malloc


Callbacks under Xbox

Discussion

Read this section carefully if you plan to use Miles timer or other callbacks (such as an end-of-sample callback). If you don't intend to use callbacks, then this section won't apply to you.

On the Xbox, callbacks are usually made to your application on a background thread. The ideal callback function is one that does nothing more than write to one or two flag variables and then immediately return back to Miles. On Xbox, other operations are allowed, but not recommended!

So, unlike MacOS 9 or PS2, you can do whatever you want inside a Miles callback on the Xbox - there are no OS-mandated restrictions. However, if you want to maintain easily ported code, then you should read about the callback restrictions for the other platforms you intend to support. Other platforms are much more strict than Xbox when it comes to callbacks.

In any case, you do have to take general multithread precautions in your callbacks. For example, if you use the C runtime library inside a callback, then you need to link with the multithreaded libraries. If you access your own internal data structures, then you need to make sure that the accessor functions can be called by two threads at once (unless you protect with a critical section lock).

Also remember that all global or static variables that are modified by a callback function must be declared with the volatile modifier. Otherwise, the callback function and the foreground may not be able to communicate after the compiler has performed all of its optimizing tricks.

You should also minimize the total amount of work inside a Miles callback. During a callback, Miles is suspended, so other background tasks won't run - mixing will be interrupted, for example, if you take too long.

Again, though, the best advice for callbacks is to simply post a message or set a flag that can be operated on by your foreground task. This technique works on all platforms and you'll never need to worry about the complications that multithreading can cause.

Next Topic (Sharing the CPU under Xbox)

Previous Topic (Memory management under Xbox)

Group: Overview for Microsoft Xbox


Sharing the CPU under Xbox

Discussion

On the Xbox, what little work Miles has to do in software (MP3 decompression, for example) is done on a background thread. You don't have to do anything special to share the CPU - everything is handled automatically.

Next Topic (Call Logging under Xbox)

Previous Topic (Callbacks under Xbox)

Group: Overview for Microsoft Xbox


Call Logging under Xbox

Discussion

Miles contains a powerful diagnostic feature that allows developers to create a timestamped list of all of their application's foreground Miles calls, along with their parameters and results. The call log will be sent to an application callback routine registered with AIL_register_trace_callback, or to a plain text file if no debug-trace callback function has been registered by the application.

To take advantage of MSS's built-in logging without recompiling your application, just create a text file called "mss_debug_log.txt" in the root directory of your Xbox hard drive (xe:\ from a PC, or d:\ inside a running Xbox application). If this file exists, then, during execution of all subsequent Miles calls, a timestamped API call log will be written to the file.

DirectSound itself also issues warnings to the output debug console, so you can watch that as well.

Next Topic (Miles Example for Xbox)

Previous Topic (Sharing the CPU under Xbox)

Group: Overview for Microsoft Xbox
Related Functions: AIL_register_trace_callback
Related FAQs: My application is crashing - what should I try?, Where is the Miles source code? How can I rebuild it (in debug mode)?


Miles Example for Xbox

Discussion

The Miles SDK supplies a simple example program for Xbox that demonstrates most of the handy Miles features. To build this example in an IDE-based environment, just create a new project, include MilesXbox.CPP to the project, and then add the Miles libraries (MSSXbox.lib, OggXbox.lib, and MP3Xbox.lib to the project).

The Xbox example file is found in the \src\examples directory. You should also copy the "\examples\media" directory to "xe:\media" on the Xbox.

We also ship the Miles for Xbox example pre-built, so that you can try it immediately. To use it, copy the MilesXbox.xbe file into the root directory of the Xbox, and then make a folder on the Xbox called "media" and copy the contents of the Miles media directory inside.

Previous Topic (Call Logging under Xbox)

Group: Overview for Microsoft Xbox


Overview for Microsoft Xbox 360

Discussion

Miles is now available for Microsoft's newest Xbox console. The Xbox 360 is wonderful to develop for - good tools and fast, fast hardware is a nice combination.

The Playstation 2 and Xbox 360 versions of Miles are the most optimized of all of the Miles platforms. We have spent a lot getting things super-fast for these platforms.

Miles is extremely easy to use and integrate on Xbox 360. We'll discuss everything you need to know to get up and running!

Overview for Microsoft Xbox 360
Installation for Xbox 360
Integrating Miles into a Xbox 360 Build Environment
Distributing Miles with Xbox 360 Applications
Sound under Xbox 360
Memory management under Xbox 360
Callbacks under Xbox 360
Sharing the CPU under Xbox 360
Call Logging under Xbox 360
Miles Example for Xbox 360


Installation for Xbox 360

Discussion

To install for Xbox 360, you simply have to run the self-installer that you download from our web site.

All installation options are largely automatic, and will not require much further user input unless you would like to change anything (like the installation directory).

Next Topic (Integrating Miles into a Xbox 360 Build Environment)

Group: Overview for Microsoft Xbox 360


Integrating Miles into a Xbox 360 Build Environment

Discussion

To build an application that uses Miles, you must include the Miles SDK in the build process. There are four simple steps to do this:

1) Include MSS.H in your source files.

2) Link with the MSSXenon.LIB or MSSXenon.LTCG.LIB libraries. Using the LTCG library will result in slightly better performance and memory use, but it takes longer to link, and Edit and Continue will no longer work.

3) If you are using MP3 data, link with the MP3xenon.LIB or MP3xenon.LTCG.LIB libraries. If you are using Ogg Vorbis data, link with the Oggxenon.LIB or Oggxenon.LTCG.LIB libraries. If you are using XMA data, link with the XMAxenon.LIB or XMAXenon.LTCG.LIB libraries. Don't forget the Register_RIB calls needed to enable these libraries.

4) If you are the software DSP filters, link with the fltxenon.LIB or fltxenon.LTCG.LIB libraries.

And that's it - you should now be able to call the Miles functions!

Next Topic (Distributing Miles with Xbox 360 Applications)

Previous Topic (Installation for Xbox 360)

Group: Overview for Microsoft Xbox 360
Related Functions: Register_RIB


Distributing Miles with Xbox 360 Applications

Discussion

Miles is supplied as a static library on the Xbox 360, so once you have linked your EXE, you don't need to distribute any other files.

Next Topic (Sound under Xbox 360)

Previous Topic (Integrating Miles into a Xbox 360 Build Environment)

Group: Overview for Microsoft Xbox 360


Sound under Xbox 360

Discussion

For digital audio output, Miles for Xbox 360 uses the XAudio system library. Miles only uses one XAudio voice - we do everything else in software for maximum speed (we are much faster than the Xbox system library (which are also software based). We do all of our work on a background CPU, so you can play hundreds of digital samples at once with no CPU hit on the main CPU at all!

The Miles Sound System on Xbox 360 supports uncompressed, IMA ADPCM, MP3, Ogg Vorbis, and XMA digital sound. IMA, Ogg Vorbis, and MP3 are not natively supported by the Xbox, but Miles makes the decompression and streaming to the sound hardware seamless - they just take a little more CPU. For basic performance calculations, playing 32 uncompressed samples takes 7% of the background CPU, playing 32 IMA ADPCM samples takes 10%, playing 32 MP3 samples takes 19%, and playing 32 Ogg samples takes about 35%. The MP3 is so fast due to writing almost the entire decoder in optimized PPC assembly.

The Xbox 360 also supports full 5.1 discrete audio. You can set the volume levels of the 5.1 individual channels with the AIL_set_sample_51_volume_pan or AIL_set_sample_51_volume_levels functions.

The Xbox 360 doesn't have dedicated MIDI hardware, so Miles uses its built-in DLS synthesizer for all MIDI playback. This has the added advantage of allowing you to author custom DLS instrument sets to optimize memory use.

And that's pretty much it - Miles is a piece of cake to use on the Xbox 360.

Next Topic (Memory management under Xbox 360)

Previous Topic (Distributing Miles with Xbox 360 Applications)

Group: Overview for Microsoft Xbox 360
Related Functions: AIL_set_sample_51_volume_levels, AIL_set_sample_51_volume_pan


Memory management under Xbox 360

Discussion

By default on the Xbox 360, Miles simply requests memory directly from the OS.

You can, of course, intercept these memory allocation requests with the AIL_mem_use_malloc and AIL_mem_use_free functions.

Next Topic (Callbacks under Xbox 360)

Previous Topic (Sound under Xbox 360)

Group: Overview for Microsoft Xbox 360
Related Functions: AIL_mem_use_free, AIL_mem_use_malloc


Callbacks under Xbox 360

Discussion

Read this section carefully if you plan to use Miles timer or other callbacks (such as an end-of-sample callback). If you don't intend to use callbacks, then this section won't apply to you.

On the Xbox 360, callbacks are usually made to your application on a background thread running on the CPU core specified by the AIL_CPU_AFFINITY preference. The ideal callback function is one that does nothing more than write to one or two flag variables and then immediately return back to Miles. On Xbox 360, other operations are allowed, but not recommended!

So, unlike MacOS 9 or PS2, you can do whatever you want inside a Miles callback on the Xbox 360 - there are no OS-mandated restrictions. However, if you want to maintain easily ported code, then you should read about the callback restrictions for the other platforms you intend to support. Other platforms are much more strict than Xbox 360 when it comes to callbacks.

In any case, you do have to take general multithread precautions in your callbacks. For example, if you use the C runtime library inside a callback, then you need to link with the multithreaded libraries. If you access your own internal data structures, then you need to make sure that the accessor functions can be called by two threads at once (unless you protect with a critical section lock).

Also remember that all global or static variables that are modified by a callback function must be declared with the volatile modifier. Otherwise, the callback function and the foreground may not be able to communicate after the compiler has performed all of its optimizing tricks.

You should also minimize the total amount of work inside a Miles callback. During a callback, Miles is suspended, so other background tasks won't run - mixing will be interrupted, for example, if you take too long.

Again, though, the best advice for callbacks is to simply post a message or set a flag that can be operated on by your foreground task. This technique works on all platforms and you'll never need to worry about the complications that multithreading can cause.

Next Topic (Sharing the CPU under Xbox 360)

Previous Topic (Memory management under Xbox 360)

Group: Overview for Microsoft Xbox 360
Related Basic Types: MILES_PREFERENCES


Sharing the CPU under Xbox 360

Discussion

On the Xbox 360, the work that Miles does (MP3 decompression, for example) is done on a background thread on another CPU. You don't have to do anything special to share the CPU - everything is handled automatically. If you need to associate a particular CPU core with the background thread used by Miles, see the AIL_CPU_AFFINITY preference for more information.

Next Topic (Call Logging under Xbox 360)

Previous Topic (Callbacks under Xbox 360)

Group: Overview for Microsoft Xbox 360
Related Basic Types: MILES_PREFERENCES


Call Logging under Xbox 360

Discussion

Miles contains a powerful diagnostic feature that allows developers to create a timestamped list of all of their application's foreground Miles calls, along with their parameters and results. The call log will be sent to an application callback routine registered with AIL_register_trace_callback, or to a plain text file if no debug-trace callback function has been registered by the application.

To take advantage of MSS's built-in logging without recompiling your application, just create a text file called "mss_debug_log.txt" in the root directory of your Xbox 360 hard drive (xe:\ from a PC, or d:\ inside a running Xbox application). If this file exists, then, during execution of all subsequent Miles calls, a timestamped API call log will be written to the file.

DirectSound itself also issues warnings to the output debug console, so you can watch that as well.

Next Topic (Miles Example for Xbox 360)

Previous Topic (Sharing the CPU under Xbox 360)

Group: Overview for Microsoft Xbox 360
Related Functions: AIL_register_trace_callback
Related FAQs: My application is crashing - what should I try?, Where is the Miles source code? How can I rebuild it (in debug mode)?


Miles Example for Xbox 360

Discussion

The Miles SDK supplies a simple example program for Xbox that demonstrates most of the handy Miles features. To build this example in an IDE-based environment, just create a new project, include MilesXenon.CPP to the project, and then add the Miles libraries (MSSXenon.lib, OggXenon.lib, and MP3Xenon.lib to the project).

The Xbox example file is found in the \src\examples directory. You should also copy the "\examples\media" directory to "xe:\media" on the Xbox.

We also ship the Miles for Xbox 360 example pre-built, so that you can try it immediately. To use it, copy the MilesXenon.exe file into the root directory of the 360, and then make a folder on the Xbox called "media" and copy the contents of the Miles media directory inside.

Previous Topic (Call Logging under Xbox 360)

Group: Overview for Microsoft Xbox 360


Overview for MacOS: Miles on Macintosh

Discussion

The Miles Sound System has supported MacOS since the MacOS 8.x days! MacOS is strange to develop under - some pieces are advanced, some pieces seem crazily backwards. However, MacOS X now finally provides a modern and fun environment to develop on.

Miles is easy to use and integrate under this platform. This chapter will discuss everything you need to know!

Overview for MacOS: Miles on Macintosh
Installation for MacOS
Sound under MacOS
Integrating Miles into a MacOS Build Environment
Distributing Miles with MacOS Applications
Filenames on MacOS
Memory management under MacOS
Callbacks under MacOS
Sharing the CPU under MacOS
Call Logging under MacOS
Miles Examples for MacOS


Installation for MacOS

Discussion

The Miles PPC SDK is provided as a self-extracting compressed archive in MacBinary format. To install it, simply double-click on the MilesSDK.sit.bin file that you downloaded from our ftp site.

The Miles x86 SDK is provided as a compressed disc image (dmg file). To install it, first mount the dirve image by double clicking on it. Then just drag the files to a directory on your hard drive.

Once installed, you can access this documentation online by clicking on the Miles SDK Help alias in the Miles SDK folder.

Next Topic (Sound under MacOS)

Group: Overview for MacOS: Miles on Macintosh


Sound under MacOS

Discussion

For digital output, the Miles Sound System uses the Sound Manager. Miles allocates a single sound buffer, and then mixes all of its sound channels into that single buffer.

For MIDI output, you use MSS's internal DLS software synthesizer. On Classic MacOS, Miles can also use QuickTime as a MIDI output layer, but QuickTime uses a lot more CPU time.

Next Topic (Integrating Miles into a MacOS Build Environment)

Previous Topic (Installation for MacOS)

Group: Overview for MacOS: Miles on Macintosh


Integrating Miles into a MacOS Build Environment

Discussion

To build an application that uses MSS, you must include the MSS SDK in the build process. There are four simple steps to do this:

1) Include MSS.H in your source files.

2) Link with the correct shared library. For Classic MacOS, use the Miles Shared Library file. For Carbon CFM (which will run on MacOS 8 through MacOS X), use the Miles Carbon Library file. For Carbon Mach-O PPC (which will only run on MacOS X), use the libMilesMachO.dylib file. And for Carbon Mach-O x86, use the libMilesMachOx86.dylib file. In CodeWarrior or Xcode, you usually just have to drop the file into your project).

3) Place the Miles Shared Library, the Miles Carbon Library, the libMilesMachO.dylib, or the libMilesMachOx86.dylib file in the folder containing your application executable. Note that Mach-O applications place the executables for an application package in a subfolder called "Contents/MacOS". Mach-O application packages are just a defined set of folders, so to open the Contents subfolder in Finder, Control-click on the application icon and choose "Show Package Contents". Then just place the libMilesMachO.dylib file into the "Contents/MacOS" folder.

4) Copy the other files in the :redist:classic, :redist:carbon, /redist/macho, or /redist/macx86 folders into a subfolder off your application's folder.

And that's it - you should now be able to call the Miles functions!

Next Topic (Distributing Miles with MacOS Applications)

Previous Topic (Sound under MacOS)

Group: Overview for MacOS: Miles on Macintosh


Distributing Miles with MacOS Applications

Discussion

To distribute an application that uses Miles, you must include the Miles Shared Library, the Miles Carbon Library, the libMilesMachO.dylib, or the libMilesMachOx86.dylib in the same folder as your application, and you must copy the other files in the :redist:classic, :redist:carbon, /redist/macho or /redist/macx86 folders to a folder accessible by your application at run-time.

Do not place any of the Miles files in the System or Extension folders! Miles must always be placed in your application folder.

Next Topic (Filenames on MacOS)

Previous Topic (Integrating Miles into a MacOS Build Environment)

Group: Overview for MacOS: Miles on Macintosh


Filenames on MacOS

Discussion

MacOS has several different ways to specify files (mostly deriving from their long OS history).

On Carbon Mach-O, Miles uses the clean and cross-platform compatible Unix-style slash separators, for example, "redist/macho".

On Classic and Carbon CFM, you can use FSSpec's or string filenames. An FSSpec is a binary representation of a file that most of the old Mac APIs use. On Classic and Carbon CFM, you can also use the original Mac style of string filenames where ":" is used as a separator, ":redist:classic", for example.

If you rebuild the Miles source, you can also make the Mach-O version use FSSpecs, or even the Carbon CFM version to use slashes (which would only work on MacOS X, of course). For modern games, though, you will probably only use the Mach-O version anyway, so the slash style filenames is the way to go.

Next Topic (Memory management under MacOS)

Previous Topic (Distributing Miles with MacOS Applications)

Group: Overview for MacOS: Miles on Macintosh
Related Functions: AIL_WAV_file_fss_write, AIL_file_fss_attrib_write, AIL_file_fss_read, AIL_file_fss_size, AIL_file_fss_write, AIL_quick_fss_load, AIL_quick_fss_load_and_play
Related Basic Types: FSSpec


Memory management under MacOS

Discussion

By default, Miles handles memory management under MacOS by calling the MacOS memory functions directly. You can, however, override the Miles allocation and freeing functions with the AIL_mem_use_malloc and AIL_mem_use_free functions.

By default, Miles tries to allocate memory in this order:

1) Miles first tries to allocate memory from the application's memory partition.

2) Next, Miles tries to allocate memory from the MultiFinder temporary memory block.

3) Finally, Miles will try to allocate memory from the temporary system memory pool.

Using this set of memory fallbacks, Miles will usually find the memory it needs no matter where it may be hiding.

Next Topic (Callbacks under MacOS)

Previous Topic (Filenames on MacOS)

Group: Overview for MacOS: Miles on Macintosh
Related Functions: AIL_mem_use_free, AIL_mem_use_malloc


Callbacks under MacOS

Discussion

Read this section carefully if you plan to use Miles timer or other callbacks (such as an end-of-sample callback). If you don't intend to use callbacks, then this section won't apply to you.

Under MacOS X, callbacks are made to your application from a background thread. Since much of Carbon is not multi-thread safe, you must be careful with the Toolbox routines that you call during a Miles callback.

Also remember that all global or static variables that are modified by a callback function must be declared with the volatile modifier. Otherwise, the callback function and the foreground may not be able to communicate after the compiler has performed all of its optimizing tricks.

Under MacOS 9, callbacks are usually made to your application on an interrupt-based system callback. The ideal callback function is one that does nothing more than write to one or two flag variables and then immediately return back to Miles. Under MacOS, the system is in a vulnerable state inside a callback, so you must be careful what code you execute!

The most important thing to avoid in a Miles callback under MacOS 9 is calling a function that can cause memory rearrangement. That means you must not call any Toolbox, Miles or other function that may cause memory to move. Check the individual Toolbox and Miles function descriptions to make sure that it can be called at interrupt time.

You should also minimize the total amount of work inside a Miles callback. During a callback, Miles is suspended, so other background tasks won't run - mixing will be interrupted, for example, if you take too long.

Again, though, the best advice for callbacks is to simply post a message or set a flag that can be operated on by your foreground task. This technique works on all platforms and you'll never need to worry about the complications that multithreading can cause.

Next Topic (Sharing the CPU under MacOS)

Previous Topic (Memory management under MacOS)

Group: Overview for MacOS: Miles on Macintosh
Related FAQs: What's the deal with callbacks - are they threads, interrupts, system timers, or what?


Sharing the CPU under MacOS

Discussion

Under MacOS X, Miles does most of its work in a background thread. Again, this means that Miles usually does its work without you even having to worry about it and that the mixing and buffer submission to the sound hardware all happens without your intervention.

The only time on MacOS X, that you may need to specifically give Miles CPU time is if the system thread scheduler starts performing badly and the background Miles thread starves. Under the MacOS X, the thread scheduler usually has the most trouble when performing disk I/O.

Miles provides several techniques to handle thread-starvation. See the AIL_get_timer_highest_delay function as well as the "My sound is skipping on Windows or MacOS X - what can I do?" FAQ for more details.

Under MacOS 9 and below, Miles does most of its work in background interrupt functions. This means that Miles usually does its work without you even having to worry about it. The mixing and buffer submission to Sound Manager all happens without your intervention.

The only time on MacOS 9 and below that you may need to specifically give Miles CPU time is if you are using the QuickTime MIDI synthesizer which requires you to service it with the AIL_serve function. The Miles synthesizer usually sounds better and takes less CPU time, though, so this usually is unnecessary.

Next Topic (Call Logging under MacOS)

Previous Topic (Callbacks under MacOS)

Group: Overview for MacOS: Miles on Macintosh
Related Functions: AIL_get_timer_highest_delay, AIL_serve
Related FAQs: My sound is skipping on Windows or MacOS X - what can I do?


Call Logging under MacOS

Discussion

Miles contains a powerful diagnostic feature that allows developers to create a timestamped list of all of their application's foreground Miles calls, along with their parameters and results. The call log will be sent to an application callback routine registered with AIL_register_trace_callback, or to a plain text file if no debug-trace callback function has been registered by the application.

To take advantage of MSS's built-in logging without recompiling your application, just create a text file called "MssDebug.log" in your application directory. If this file exists, then, during execution of all subsequent Miles calls, a timestamped API call log will be written to the file.

Next Topic (Miles Examples for MacOS)

Previous Topic (Sharing the CPU under MacOS)

Group: Overview for MacOS: Miles on Macintosh
Related Functions: AIL_register_trace_callback
Related FAQs: My application is crashing - what should I try?, Where is the Miles source code? How can I rebuild it (in debug mode)?


Miles Examples for MacOS

Discussion

The Miles SDK supplies a bunch of simple console-style example programs for MacOS. To build them, just create a new project in CodeWarrior or Xcode, and then drop the appropriate example file and the Miles library into the project window.

Check out all of the examples in the src/examples folder.

Previous Topic (Call Logging under MacOS)

Group: Overview for MacOS: Miles on Macintosh


Overview for DOS: Miles on DOS with 32-bit DOS Extenders

Discussion

The Miles Sound System has always supported DOS (it was John Miles' first supported platform way back in 1991)! DOS is a little tough to develop on nowadays though, because most of the tools necessary to do the job are incompatible with today's machines, or are even discontinued completely.

This platform is almost exclusively used by standup video-arcade embedded machines now. It will be interesting to watch whether this market will gradually migrate to Linux in the future.

Not all of the Miles SDK is supported on DOS - there is no low-bandwidth voice chat codec, hardware 3D, or microphone input support on this platform.

As it was the initial Miles platform, MSS is extremely easy to use and integrate under DOS. This chapter will discuss everything you need to know!

Overview for DOS: Miles on DOS with 32-bit DOS Extenders
Installation for DOS
Sound under DOS
Integrating Miles into a DOS Build Environment
Distributing Miles with DOS Applications
Memory management under DOS
Callbacks under DOS
Sharing the CPU under DOS
Call Logging under DOS
Miles Examples for DOS


Installation for DOS

Discussion

The Miles SDK is installed for DOS just like it is for Win32 - see the Installation for Win32 Section for details. You will need some version of Windows to perform the installation.

Next Topic (Sound under DOS)

Previous Topic (Overview for DOS: Miles on DOS with 32-bit DOS Extenders)

Group: Overview for DOS: Miles on DOS with 32-bit DOS Extenders
Related Sections: Installation for Win32


Sound under DOS

Discussion

Under DOS, the Miles Sound System provides of a set of loadable drivers, or device-dependent code modules which interact with the host machine's sound-generating hardware, and Miles itself.

Audio driver files for the DOS version of MSS can be recognized by their ".DIG" and ".MDI" file suffixes for the digital audio and XMIDI music drivers, respectively. MSS's driver file structure is the key to its expandability and ease of use. Each unique sound module standard supported by MSS has its own driver which contains enough self-descriptive information to drive its sound module under control of an application developed before that sound module was supported. This "encapsulated" approach helps guard against obsolescence when new sound hardware appears in the marketplace. It is possible to add to an application's list of compatible sound modules without changing a single byte of existing application code, unless unique new performance features must be supported. Even after a product's release, new drivers and data files can be distributed to end-users via the Internet.

Each DOS driver is written in real-mode 80x86 assembly language or C as a single-segment program containing an INT 66H interrupt handler, various general-purpose support routines, and device-specific code for the supported audio hardware. The drivers' low-level functions are never directly called by the application. Instead, most driver functions serve to pass data back and forth between the sound module and the SDK, while others provide the driver with a means of describing its own capabilities in terms the SDK can understand. DOS drivers for MSS conform to the MSS DDK, which is an "open standard" available to all OEMs, developers, and other interested parties. This standard is defined by the MDD DDK documentation, provided with this documentation.

In fact, the majority of the loadable sound drivers were actually written by the sound card manufacturers. If you have a card that you'd like to be supported, give the manufacturer a call and have them get in touch with us to obtain a DDK.

Next Topic (Integrating Miles into a DOS Build Environment)

Previous Topic (Installation for DOS)

Group: Overview for DOS: Miles on DOS with 32-bit DOS Extenders


Integrating Miles into a DOS Build Environment

Discussion

To build an application that uses MSS, you must include the MSS SDK in the build process. Miles for DOS supports either the Watcom C/C++ or the Borland C++ with Powerpack environments. There are three simple steps to do this:

1) Include MSS.H in your source files.

2) Link with the MSSWAT.LIB or MSSBOR.LIB library.

3) Copy the files in the \redist directory into a subdirectory off your application's directory.

And that's it - you should now be able to call the Miles functions!

Next Topic (Distributing Miles with DOS Applications)

Previous Topic (Sound under DOS)

Group: Overview for DOS: Miles on DOS with 32-bit DOS Extenders


Distributing Miles with DOS Applications

Discussion

To distribute an application that uses Miles, you must include the files in the \redist directory in a directory accessible by your application at runtime.

After you perform your installation, you should also then run the SetSound utility to allow the user to choose the type of sound card in his machine.

Next Topic (Memory management under DOS)

Previous Topic (Integrating Miles into a DOS Build Environment)

Group: Overview for DOS: Miles on DOS with 32-bit DOS Extenders
Related Sections: SETSOUND - MSS Sound Configuration Utility


Memory management under DOS

Discussion

By default, Miles handles memory management under DOS by calling the C runtime malloc and free functions directly and then locking the memory with AIL_vmm_lock.

You can, however, override the Miles allocation and freeing functions with the AIL_mem_use_malloc and AIL_mem_use_free functions.

Next Topic (Callbacks under DOS)

Previous Topic (Distributing Miles with DOS Applications)

Group: Overview for DOS: Miles on DOS with 32-bit DOS Extenders
Related Functions: AIL_mem_use_free, AIL_mem_use_malloc, AIL_vmm_lock


Callbacks under DOS

Discussion

Read this section carefully if you plan to use Miles timer or other callbacks (such as an end-of-sample callback). If you don't intend to use callbacks, then this section won't apply to you.

Under DOS, callbacks are usually made to your application on a background interrupt. The ideal callback function is one that does nothing more than write to one or two flag variables and then immediately return back to Miles. Under DOS, the system is in a vulnerable state inside a callback, so you must be careful what code you execute!

The most important thing to remember is you can't call any functions that call any DOS interrupt. I/O is especially not allowed!

Only 32 KB of stack space is available to DOS callback functions. This amount is sufficient for nearly all "callback-safe" actions. Any function that requires a larger stack may switch to its own with the AIL_switch_stack function.

All code and data accessed by the callback function should be page-locked for use in a VMM environment. All callback functions must also be compiled with stack checking turned off. This usually requires a change to your compiler command line (add "-s" in Watcom C++, for example).

Also remember that all global or static variables that are modified by a callback function must be declared with the volatile modifier. Otherwise, the callback function and the foreground may not be able to communicate after the compiler has performed all of its optimizing tricks.

You should also minimize the total amount of work inside a Miles callback. During a callback, Miles is suspended, so other background tasks won't run - mixing will be interrupted, for example, if you take too long.

Again, though, the best advice for callbacks is to simply post a message or set a flag that can be operated on by your foreground task. This technique works on all platforms and you'll never need to worry about the complications that multithreading can cause.

Next Topic (Sharing the CPU under DOS)

Previous Topic (Memory management under DOS)

Group: Overview for DOS: Miles on DOS with 32-bit DOS Extenders
Related Functions: AIL_switch_stack
Related FAQs: What's the deal with callbacks - are they threads, interrupts, system timers, or what?


Sharing the CPU under DOS

Discussion

Under DOS, Miles does most of its work in background interrupts. This means that Miles usually does its work without you even having to worry about it. The mixing and buffer submission to low-level sound drivers all happens without your intervention.

The only time you may need to specifically give Miles CPU time is when you are streaming files with the high-level streaming functions. DOS applications can't do I/O in the background, so if you are streaming, you have to periodically call AIL_service_stream.

Miles does take control of the system timer interrupt. If your game already uses the hardware timer, then you are usually best off converting your interrupt routines into Miles timers. They are just as accurate and allow everything to get along nicely. If you must control the clock, then contact RAD for details on patching the required functions in the Miles source code.

Next Topic (Call Logging under DOS)

Previous Topic (Callbacks under DOS)

Group: Overview for DOS: Miles on DOS with 32-bit DOS Extenders
Related Functions: AIL_service_stream


Call Logging under DOS

Discussion

Miles contains a powerful diagnostic feature that allows developers to create a timestamped list of all of their application's foreground Miles calls, along with their parameters and results. The call log will be sent to an application callback routine registered with AIL_register_trace_callback, or to a plain text file if no debug-trace callback function has been registered by the application.

To take advantage of MSS's built-in logging without recompiling your application, set the DOS environment variable "MSS_DEBUG" to a filename to write the log to. During execution of all subsequent Miles calls, a timestamped API call log will be written to the specified file.

For example, to dump the API call log to a file name foo.txt, execute the following command at the DOS prompt:

set MSS_DEBUG=foo.txt

You can also view MSS's internal function calls by running the extra command, "set MSS_SYS_DEBUG=1".

Next Topic (Miles Examples for DOS)

Previous Topic (Sharing the CPU under DOS)

Group: Overview for DOS: Miles on DOS with 32-bit DOS Extenders
Related Functions: AIL_register_trace_callback
Related FAQs: My application is crashing - what should I try?, Where is the Miles source code? How can I rebuild it (in debug mode)?


Miles Examples for DOS

Discussion

The Miles SDK supplies several example programs for DOS. To create these examples, you can simply run the Debug.BAT or Release.BAT in the source directory.

The DOS example files are found in the \src\examples directory. There are examples of digital audio playback, MIDI playback (hardware based and DLS), DSP filters, and more.

Previous Topic (Call Logging under DOS)

Group: Overview for DOS: Miles on DOS with 32-bit DOS Extenders


The Digital Audio Pipeline

Discussion

The Digital Audio Pipeline
How do I use multi-channel sound output in Miles?
AIL_sample_output_levels returns the final mixer level-scaling factors for one or more combinations of source channels and destination speakers.


FAQs and How Tos

Discussion

The Miles Sound System is a big API - pretty much anything related to audio is in there. MSS is logical, though, so once you "get it", most things will be second nature. Coming up to speed, however, can be a little daunting.

This is probably most important section in that regard - it will get you up and running quickly - pore over it carefully!

FAQs and How Tos
Introduction
How do I initialize the Miles Sound System for use?
How do I play a digital sound?
How do I use multi-channel sound output in Miles?
What's the best way to port my older Miles application to MSS 7?
How do I play an XMIDI or MIDI file?
How do I play an XMIDI file with a DLS instrument set?
How do I stream a file off a hard disk or CD?
How do I play a track off a CD?
How do I loop a track off a CD?
I used an older version of Miles and now my volume and pan calls are weird - what's going on? And what's with the two types of volume functions?
What kind of audio decompression does Miles support?
What is MPEG Audio and MP3?
What MP3 encoder should I use?
I can't get Miles to play an MP3, XMA, or Ogg Vorbis file - what's going on?
How can I lower the CPU hit of playing an MP3 file?
I'm getting a glitch when I loop an MP3 or ADPCM file - what can I do?
How do I apply a low-pass filter?
How do I set a DSP filter on a sample?
How much CPU do the various filters use?
How can I play two HSAMPLEs from the same memory address?
When can I free the memory I gave to MSS?
How do I start an audio file somewhere in the middle?
How do I smoothly ramp up or ramp down the volume of a sample over time?
How do I play a 3D digital sound?
My 3D sound isn't falling off like I expected - what's going on?
How can I assign 3D positions to stereo samples?
My 3D audio is a lot louder than my 2D audio - what can I do?
How do I set an environmental reverb room style?
How does Miles do sound prioritization?
On the Sony PS2, how can I use the IOP or SPU memory to hold my audio?
I can't seem to change the volume of my XMIDI sequences, what's going on?
What's the deal with callbacks - are they threads, interrupts, system timers, or what?
How much latency does Miles have?
My sound is skipping on Windows or MacOS X - what can I do?
My application is crashing - what should I try?
Where is the Miles source code? How can I rebuild it (in debug mode)?
How can I tell what version of Miles that I have?
What is the latest version of MSS?
How do I use a Unicode path on Windows?
How do I access files from a big packed file?
I'm setting a preference and it isn't having any effect - what's going on?
I want a small installation - do I need all of the files in the \redist directories?
I'm using Windows 9x or NT - do I have to call the AIL_mem_alloc_lock function?
How careful do I have to be when shutting down?
This function returns a bunch of return data, but I only want one value - is there a simpler way to use it?
The Internet voice chat example has a lot of latency or it doesn't work on my LAN - what's going on?
What are these ASI and FLT files? What is RIB?


How do I initialize the Miles Sound System for use?

Miles Sound System SDK 7.2a

Q:

How do I initialize the Miles Sound System for use?

A:

The first step in using Miles is to initialize the library. You can initialize Miles with the full API or the Quick API.

To open Miles with the full Miles API, follow these steps:

1) On Win32, Win64, MacOS and Linux: call AIL_set_redist_directory to specify the game's local directory that contains the files from the SDK's platform-specific "\redist" directory. (This directory is relative to the location of the Miles library file, so if you are using a relative path, make sure it is relative to the right directory!)

2) On platforms that don't support x86 (Win32) DLLs, including Xbox, Wii, PS2, PS3, Xbox 360, and DOS: call Register_RIB to load modules such as the MP3, Ogg Vorbis, or Voxware decoders if you need them. Usually, you'll just need to add "Register_RIB(MP3Dec)" and/or "Register_RIB(OggDec)". Similarly, "Register_RIB(DSP)" is needed on these platforms to enable DSP filtering. The SRS Circle Surround and Dolby Surround options (where applicable) require "Register_RIB(SRS)" and "Register_RIB(DolbySurround)" calls, respectively. DTS support on the Sony PS2 requires Register_RIB(DTS).

3) Call AIL_startup to initialize Miles.

4) Call the appropriate open function for the subsystems that you plan to use: AIL_open_digital_driver for 2D digital audio, AIL_open_XMIDI_driver for MIDI, etc. Under Win32 and Win64, make sure that you have created an HWND at this point (DirectSound requires this).

If you use the full Miles API to initialize Miles, be sure to call AIL_shutdown to shut everything down when your game is closed.

To open Miles with the Quick API, follow these steps:

1) On Win32, Win64, MacOS and Linux: call AIL_set_redist_directory to specify the game's local directory that contains the files from the SDK's platform-specific "\redist" directory. (This directory is relative to the location of the Miles library file, so if you are using a relative path, make sure it is relative to the right directory!)

2) On platforms that don't support x86 (Win32) DLLs, including Xbox, Wii, PS2, PS3, Xbox 360, and DOS: call Register_RIB to load modules such as the MP3, Ogg Vorbis, or Voxware decoders if you need them. Usually, you'll just need to add "Register_RIB(MP3Dec)" and/or "Register_RIB(OggDec)". Similarly, "Register_RIB(DSP)" is needed on these platforms to enable DSP filtering. The SRS Circle Surround and Dolby Surround options (where applicable) require "Register_RIB(SRS)" and "Register_RIB(DolbySurround)" calls, respectively. DTS support on the Sony PS2 requires Register_RIB(DTS).

3) Call AIL_quick_startup with the appropriate settings for your application. For Win32 and Win64, make sure that you have created an HWND at this point (DirectSound requires it).

If you use the Quick API to initialize Miles, be sure to call AIL_quick_shutdown to shut everything down when your game is closed.

Next Topic (How do I play a digital sound?)

Group: FAQs and How Tos
Related Functions: AIL_open_XMIDI_driver, AIL_open_digital_driver, AIL_quick_shutdown, AIL_quick_startup, AIL_set_redist_directory, AIL_shutdown, AIL_startup, Register_RIB


How do I play a digital sound?

Miles Sound System SDK 7.2a
Q: | How do I play a digital sound?
A: | To play a digital sound with the full Miles API, follow these steps: 1) Allocate an HSAMPLE with AIL_allocate_sample_handle. 2) Load the file from the disk with AIL_file_read (or your own file IO routines). 3) Point the HSAMPLE at the loaded disk file image with AIL_set_sample_file, AIL_set_named_sample_file, or AIL_set_sample_info. 4) Finally, call AIL_start_sample to begin playing the HSAMPLE. To play a digital sound with the Quick API, follow these steps: 1) Call AIL_quick_load to load the file. 2) Play the file with AIL_quick_play.

Next Topic (How do I use multi-channel sound output in Miles?)

Previous Topic (How do I initialize the Miles Sound System for use?)

Group: FAQs and How Tos
Related Functions: AIL_allocate_sample_handle, AIL_file_read, AIL_quick_load, AIL_quick_play, AIL_set_named_sample_file, AIL_set_sample_file, AIL_set_sample_info, AIL_start_sample


How do I use multi-channel sound output in Miles?

Miles Sound System SDK 7.2a

Q:

How do I use multi-channel sound output in Miles?

A:

Sound cards and integrated PC motherboard chipsets offering more than the usual two stereo output channels have been widely available for some time, primarily to support DVD surround playback. Game developers have used various '3D sound' solutions ranging from Dolby Surround processing to elaborate head-related transfer function implementations to give players a sense of simulated spatial orientation and distance, but only a few recent titles such as Half-Life 2 have offered the ability to render in-game sound effects and dialogue through the 5.1-channel or similar multichannel speaker systems that more and more users own. In MSS version 7.0, we've given you the ability to add true multispeaker digital audio support in an afternoon's worth of coding.

What output formats are available?

The DOS and Macintosh platforms support conventional mono/stereo output formats only. Xbox and Xbox 360 are even simpler to understand -- it's inherently a 5.1-channel system. For more information on audio support on the Xbox, see the Overview for Microsoft Xbox section .

As usual, on platforms like Win32/Win64 and the Sony PS2/PS3, things get interesting. When you call AIL_open_digital_driver (or its quick API equivalent, AIL_quick_startup), you'll need to tell Miles what audio output format to use via the channels parameter. This is an integer parameter that was previously limited to values of either 1 or 2 for mono or stereo output. Beginning with MSS 7, you can also pass a value of the enum type MSS_MC_SPEC to functions that open a digital driver. A brief explanation of these options appears below.

  • MSS_MC_USE_SYSTEM_CONFIG This option causes MSS to choose an appropriate MSS_MC_SPEC setting based on the Windows control-panel settings as reported by IDirectSound::GetSpeakerConfig. This is generally the setting you should use.

  • MSS_MC_MONO Conventional monaural (single-speaker) sound. Equal to the constant 1.
  • MSS_MC_STEREO Conventional stereo sound. Equal to the constant 2. Miles's 3D positional math assumes two (left and right) speakers are in front of the listener at 45-degree angles.
  • MSS_MC_HEADPHONES Similar to MSS_MC_STEREO, but Miles assumes the speakers are positioned directly to either side of the listener.
  • MSS_MC_DOLBY_SURROUND This option assumes the user has connected a Dolby Surround-capable receiver to their (two-channel) sound card. It is identical to the Miles Dolby Surround M3D provider from earlier versions. Because DVD soundtracks downmixed to analog Dolby Surround sound pretty awful, this is no longer a very popular option for PC sound. Dolby Surround provides three logical channels (front left, front right, and monaural rear).
  • MSS_MC_SRS_CIRCLE_SURROUND SRS Circle Surround(r) is a two-channel matrix format can be thought of as an improved replacement for Dolby Surround. It is compatible with consumer receivers that support Dolby, and offers 6.1 logical channels (front left, front right, front center, subwoofer, rear left, rear right, and rear center) on native Circle Surround(r)-compatible equipment. The main drawback to Circle Surround(r) is its significantly-increased CPU overhead compared to Dolby Surround.
  • MSS_MC_40_DISCRETE This option assumes that four speakers (front left, front right, rear left, and rear right) are connected in a quadraphonic discrete configuration without the center speaker or subwoofer typical of 5.1 configurations. Not an especially-common channel configuration, except for a few diehard Led Zeppelin fans who haven't upgraded for awhile.
  • MSS_MC_51_DISCRETE Use this option to support the 'sweet spot' of current home audio systems, the 5.1-channel discrete configuration. Again, this is largely a DVD-driven phenomenon. There is a lot of hardware out there that can support 5.1 audio these days! This is the most common format on the PS3 as well.
  • MSS_MC_40_DTS Available on Sony PS2, this option provides four-channel discrete DTS encoding through the S/PDIF port. It is more efficient in terms of memory and encoding overhead than MSS_MC_51_DTS, but lacks support for the LFE and center channels. Like MSS_MC_40_DISCRETE, it assumes that at least four speakers (front left, front right, rear left, and rear right) are available.
  • MSS_MC_51_DTS Available on Sony PS2, this option provides true 5.1-channel discrete DTS encoding through the S/PDIF port. DTS is surprisingly efficient on the PS2, sounds great, and is highly recommended for apps that can afford the slight (5% or so) CPU hit.
  • MSS_MC_61_DISCRETE Similar to 5.1, but with a rear center speaker.
  • MSS_MC_71_DISCRETE Similar to 5.1, but with side surrounds. This is a very common format for multichannel sound hardware to support, but users don't tend to have room for this many speakers. The PS3 also supports this option, but there are few speakers setups that can handle it.
  • MSS_MC_81_DISCRETE Similar to 5.1, but with both side surrounds and a center rear speaker.
  • MSS_MC_DIRECTSOUND3D Uses DirectSound3D for output, bypassing the Miles internal mixer.
  • MSS_MC_EAX2 Adds hardware-accelerated environmental reverb effects, occlusion, obstruction, and per-sample wet/dry mix control to DirectSound3D.
  • MSS_MC_EAX3 Adds exclusion and several other properties to the EAX 2 feature set.
  • MSS_MC_EAX4 Higher-quality effects and new control options (see the EAX4EXAM.CPP example application), currently available only in Creative Labs' highest-end hardware.

When using the MSS_MC_USE_SYSTEM_CONFIG flag for the channels parameter, the output configuration is determined as follows (note that not all of the speaker systems are supported on all platforms):

Operating System Reports | Equivalent MSS_MC_SPEC Value
Headphones | MSS_MC_HEADPHONES
Mono speaker | MSS_MC_MONO
Quad speakers | MSS_MC_40_DISCRETE
Stereo speakers | MSS_MC_STEREO
Surround speakers | MSS_MC_SRS_CIRCLE_SURROUND
5.1 speakers | MSS_MC_51_DISCRETE
6.1 speakers | MSS_MC_61_DISCRETE
5.1 speakers | MSS_MC_51_DISCRETE
8.1 speakers | MSS_MC_81_DISCRETE

You can query the chosen MSS_MC_SPEC value by calling AIL_speaker_configuration on the returned HDIGDRIVER. Unfortunately, the control-panel or other system setting may not reflect the user's actual hardware configuration. Worst, from the sound driver's point of view, the configuration may be determined by a separate, proprietary applet -- which may or may not keep itself synchronized with the operating system settings. Further, the limited range of operating system values don't begin to address all of the possible configurations (for example, under Windows there is no option for 6.1 speakers). Therefore, it's best not to rely solely on the OS to report a meaningful speaker-configuration value; we strongly recommend offering the user the ability to select an MSS_MC_ configuration directly as part of your application's sound-options dialog. So, default to MSS_MS_USE_SYSTEM_CONFIG, but give the user the ability to override.

Understanding the DirectSound3D alternatives on Windows

On the sound card hardware, DirectSound 3D can do many of the functions that Miles provides in its software mixer. In theory, hardware mixing saves CPU time. In reality, the advantage ranges from subtle to unmeasurable! Worse, hardware processing implies hardware resources, so this means that you are limited to the number of hardware voices offered by DirectSound 3D -- typically a very small number on the order of 8 to 16.

Also note that no environmental reverb effects are supported when MSS_MC_DIRECTSOUND3D options are selected -- only the EAX options offer reverb effects in hardware. Furthermore, the DirectSound3D multispeaker positioner will work properly only if the end user's speaker configuration is set correctly in the Windows control panel and/or their sound card vendor's proprietary control application.

The EAX options add environmental reverb effects to DirectSound 3D, with all of DirectSound3D's accompanying advantages and drawbacks. But hardware acceleration of environmental reverb effects, unlike acceleration of mixing by itself, actually can save CPU time on slower machines. Unfortunately, while EAX is widely emulated in various chipsets (as well as MSS's own software mixer), there is little consistency in reverb levels and quality even among Creative Labs' own products, much less those from other vendors. If consistent reproduction across all platforms is important to your application, don't rely on hardware EAX support -- use the software mixer-based options instead.

For all of these reasons, it's better in most cases to skip the DirectSound3D/EAX options in favor of allowing the end user to select the mono, stereo, or MSS_MC_DISCRETE configuration that matches their hardware and let Miles do the mixing and environmental effects internally. Almost all games (and even next-gen console APIs) are moving towards software based sound processing - it's more reliabile, more consistent, and easier to author for.

Channel level-control options

Regardless of whether a mono, stereo, discrete multichannel, or SRS/Dolby output format is selected, the MSS software mixer gives you a couple of different ways to determine how much sound from a given HSAMPLE reaches each speaker. Obviously, the AIL_set_sample_volume_pan or AIL_set_sample_volume_levels will have the expected effect regardless of the output format. MSS 7, however, has introduced an additional scale factor that affects per-sample volume, the channel level scalar. There's one channel-level scale factor for each combination of source channel (HSAMPLE) and logical channel in the output mix (HDIGDRIVER). MSS multiplies each playing HSAMPLE's 3D/volume/pan-derived level with the channel-level scale factor at each speaker to obtain the volume at that speaker. The maximum level of each source (HSAMPLE/HSTREAM) channel at each output speaker, prior to any volume- or pan-control attenuation, may be set directly by the application via the AIL_set_sample_channel_levels function.

Many applications will never need to use AIL_set_sample_channel_levels at all. By default, MSS tries to select a reasonable mapping between source and speaker channels for a given output mode. Rules that establish the default channel-routing behavior include:

  • Mono sources played in MSS_MC_MONO output mode are sent to the only available output (speaker) channel
  • Mono sources played in stereo or multichannel output modes are sent to all available speaker channels
  • Stereo source channels are combined for MSS_MC_MONO output
  • Stereo sources played in multichannel output modes are sent to the front-left and front-right speaker channels only
  • Multichannel source channels, except LFE channels, are combined for MSS_MC_MONO output
  • In stereo or multichannel output modes, channels from multichannel sources which do not have a corresponding output speaker channel are steered based on their front/back and left/right spatial assignments. For example, a left-rear source channel would appear in the front-left channel in MSS_MC_STEREO mode. Any remaining unmapped source channels, such as center channels, are steered to both left and right destination channels. LFE source channels are never mapped to any output channel except LFE (if present).
  • When more than two source channels are mapped to a single speaker, an attenuation factor is applied to help avoid clipping distortion. The default level scalar assigned to each channel-speaker combination is 1.0 (full scale) if there are two or fewer source channels assigned to the speaker, or 2/n if more than two channels are assigned. This corresponds to 20*log(n/2) dB down from full scale, where n is the total number of channels assigned to the speaker.

Note that some aspects of this behavior are different in MSS versions 7.1a and earlier. In these earlier releases, stereo source channels were mapped arbitrarily to successive pairs of output channels, and multichannel HSAMPLEs/HSTREAMs were not supported at all.

Another point that must be emphasized is that the behavior described above is only the default. The AIL_set_sample_channel_levels function gives your MSS application complete control over the channel-steering matrices for all of its HSAMPLEs and HSTREAMs... even 3D-positioned ones, if desired! To understand how MSS applies various internally-generated and application-supplied scale factors to HSAMPLE and HSTREAM volume levels, see the Digital Audio Pipeline section.

3D control

It's possible for MSS to determine an HSAMPLE's channel levels automatically, by performing distance and directionality calculations based on the relative positions of the HSAMPLE and its HDIGDRIVER (also known as the listener) in 3D space. Positions in 3D space are specified in left-handed coordinates (+X = right, +Y = up, +Z = front) by means of the AIL_set_sample_3D_position and AIL_set_listener_3D_position functions.

Once an HSAMPLE has been placed under 3D control, a number of additional MSS API functions can be applied to the HSAMPLE. AIL_set_sample_3D_distances determines how distance-based attenuation is applied to the sound, while the AIL_set_sample_3D_cone and AIL_set_sample_3D_orientation functions give the sound a directional falloff characteristic. AIL_set_sample_3D_velocity applies Doppler shift to the sound. Similar functions apply to the listener object associated with the HDIGDRIVER. When the MSS software mixer is in use, none of the functions whose name contains '_3D_' affect HSAMPLES that have not been assigned a 3D position.

Only monaural samples can be meaningfully assigned a 3D position with AIL_set_sample_3D_position. Assigning a 3D position to a stereo sample will result in a forced downmix to mono when that HSAMPLE is processed by the software mixer. Assigning a 3D position to a multichannel sample yields undefined results which may vary from one MSS version to the next.

Even after you call AIL_set_sample_3D_position on an HSAMPLE, the sample's channel levels may still be controlled via AIL_set_sample_channel_levels. Any additional channel-level scale factors supplied by the application are simply multiplied with the results of the 3D-positioning algorithm.

Note that the only way to disable 3D spatialization of an HSAMPLE is to reinitialize it with a call to AIL_init_sample, AIL_set_sample_info, AIL_set_sample_file, or AIL_set_named_sample_file. You can tell if a given HSAMPLE has been placed under 3D control by examining the return value from AIL_sample_3D_position.

Along the same lines, note that discrete control of channel levels is available only with the MSS software mixer; it isn't possible with the DirectSound3D/EAX options. AIL_set_sample_channel_levels and AIL_sample_channel_levels don't work at all on these configurations... and all HSAMPLEs are 3D-positioned, even ones for which you've never called AIL_set_sample_3D_position. So you'll need to open another HDIGDRIVER for 2D-only sounds like menu cues and extradiagetic sound effects, unless every sound effect in your game is 3D-positional. The examms example program demonstrates this principle.

Addressing individual speakers

MSS's multichannel implementation is based on the master speaker/channel layout plan defined by Microsoft as part of their WDM driver model for Windows 98SE and Windows 2000/XP. In this scheme, up to eighteen channels are specifiable through the use of the MSS_SPEAKER enumeration:

MSS_SPEAKER enum | Abbreviation | Numeric value
MSS_SPEAKER_FRONT_LEFT | FL | 0
MSS_SPEAKER_FRONT_RIGHT | FR | 1
MSS_SPEAKER_FRONT_CENTER | FC | 2
MSS_SPEAKER_LOW_FREQUENCY | LFE | 3
MSS_SPEAKER_BACK_LEFT | BL | 4
MSS_SPEAKER_BACK_RIGHT | BR | 5
MSS_SPEAKER_FRONT_LEFT_OF_CENTER | FLoC | 6
MSS_SPEAKER_FRONT_RIGHT_OF_CENTER | FRoC | 7
MSS_SPEAKER_BACK_CENTER | BC | 8
MSS_SPEAKER_SIDE_LEFT | SL | 9
MSS_SPEAKER_SIDE_RIGHT | SR | 10
MSS_SPEAKER_TOP_CENTER | TC | 11
MSS_SPEAKER_TOP_FRONT_LEFT | TFL | 12
MSS_SPEAKER_TOP_FRONT_CENTER | TFC | 13
MSS_SPEAKER_TOP_FRONT_RIGHT | TFR | 14
MSS_SPEAKER_TOP_BACK_LEFT | TBL | 15
MSS_SPEAKER_TOP_BACK_CENTER | TBC | 16
MSS_SPEAKER_TOP_BACK_RIGHT | TBR | 17

In addition to providing destination-speaker and source-channel index values for use with AIL_set_sample_channel_levels and other functions, this table defines the order in which channels must appear in multichannel source streams. As shown in the table below, only one combination of MSS_SPEAKER output channels is valid for any given number of logical output channels. (As an example, MSS_MC_61_DISCRETE always refers to a speaker configuration consisting of the FL, FR, FC, LFE, BL, BR, and BC output channels.)

MSS_MC_SPEC enum | Physical/logical channels | Logical MSS_SPEAKER array
MSS_MC_DIRECTSOUND3D | 0/0 | NA
MSS_MC_EAX2 | 0/0 | NA
MSS_MC_EAX3 | 0/0 | NA
MSS_MC_EAX4 | 0/0 | NA
MSS_MC_MONO | 1/1 | FL
MSS_MC_STEREO | 2/2 | FL,FR
MSS_MC_HEADPHONES | 2/2 | FL,FR
MSS_MC_40_DISCRETE | 4/4 | FL,FR,BL,BR
MSS_MC_DOLBY_SURROUND | 2/3 | FL,FR,BC
MSS_MC_SRS_CIRCLE_SURROUND | 2/7 | FL,FR,FC,LF,BL,BR,BC
MSS_MC_51_DISCRETE | 6/6 | FL,FR,FC,LF,BL,BR
MSS_MC_61_DISCRETE | 7/7 | FL,FR,FC,LF,BL,BR,BC
MSS_MC_71_DISCRETE | 8/8 | FL,FR,FC,LF,BL,BR,SL,SR
MSS_MC_81_DISCRETE | 9/9 | FL,FR,FC,LF,BL,BR,BC,SL,SR

Your application doesn't normally need to worry about specific channel-ordering issues because MSS keeps track of which MSS_SPEAKERs are valid for a given HSAMPLE and output driver. And again, this is all moot when using DirectSound3D/EAX, because you don't have any control over individual channel levels to begin with.

You can obtain the number of physical and logical channels in use by calling AIL_speaker_configuration, as well as the MSS_MC_SPEC value passed to (or chosen by) AIL_open_digital_driver. As can be seen in the table above, these will be identical for all conventional (non-matrix) discrete formats, while matrix formats such as Dolby and SRS Circle Surround(r) can map three or more logical channels onto two physical channels. DirectSound3D and EAX will report zero physical channels and zero logical channels, since Windows insulates the application from these details.

Authoring multichannel content for MSS

MSS can play two types of multichannel audio files: Ogg Vorbis files and PCM .WAV files with WAVE_FORMAT_EXTENSIBLE headers. PCM .WAV files can only be played from memory; they cannot be played with AIL_open_stream. Multichannel Ogg Vorbis files, on the other hand, are compatible with all MSS playback functions.

Multichannel PCM .WAV file headers have a 32-bit channel mask value whose bits determine which speakers are intended to render the file's source channels. The so-called dwChannelMask value can be passed to AIL_set_sample_info at sample-initialization time via the AILSOUNDINFO structure's channel_mask member, and queried at any time by AIL_sample_channel_count. It should always be 0xFFFFFFFF (~0U) for a standard mono or stereo HSAMPLE. If not all of the mask bits are set, this means that the specified HSAMPLE is a multichannel sample. In this case, the values of the first 18 bits equal 1 if the corresponding MSS_SPEAKER channel is present, or 0 if not. (The LSB, i.e., dwChannelMask & 0x01, corresponds to MSS_SPEAKER_FRONT_LEFT.) The values of subsequent mask bits (bit 18 and beyond) are undefined and should be ignored.

Small (< 2 GB total) multichannel PCM .WAV files can be created through the use of the WAVMUX.EXE utility. Using WAVMUX.EXE, it's possible to create a PCM .WAV file that contains gaps in its channel mask. For instance, the command

wavmux output.wav none none none none back_left.wav back_right.wav

creates a multichannel (WAVE_FORMAT_EXTENSIBLE) .WAV file called output.wav with only its back-left and back-right channels valid. Although this is a two-channel .WAV file, it is not a "stereo" .WAV file, but rather a multichannel .WAV with a dwChannelMask value of 0x0030. Its two channels will be identified as "BL" and "BR" in the Miles Sound Player.

Miles fully supports multichannel Ogg Vorbis files. Creating a multichannel Ogg Vorbis file can be as simple as dragging the desired multichannel .WAV file onto an OggDrop window. However, dwChannelMask information from the .WAV source is not preserved in a multichannel Ogg Vorbis file. Instead, the channel layout of an Ogg Vorbis file is inferred from its channel count, according to the following table:

# of channels in Ogg Vorbis file | Effective dwChannelMask | Equivalent MSS_SPEAKER array
1 | ~0U (conventional mono) | (Mono, stored as FL channel)
2 | ~0U (conventional stereo) | FL,FR
3 | 0x0103 (multichannel) | FL,FR,BC
4 | 0x0033 (multichannel) | FL,FR,BL,BR
5 | 0x0037 (multichannel) | FL,FC,FR,BL,BR
6 | 0x003F (multichannel) | FL,FR,FC,LF,BL,BR
>6 | (1 << n)-1 | First n channels in MSS_SPEAKER order

Conventional stereo samples are somewhat faster to process than 2-channel multichannel samples, so MSS assumes that all two-channel Ogg Vorbis files and all standard two-channel .WAV files are stereo samples destined for the front-left/front-right speakers. If you want to perform arbitrary channel steering on a stereo file, you'll need to encode it as a multichannel .WAV file with two valid channels.

Working with speaker positions and falloff

When MSS opens an HDIGDRIVER in configurations other than DirectSound3D/EAX, it chooses a reasonable set of default positions for the speakers in the configuration. In most cases, the speakers with directional characteristics (i.e., other than the subwoofer/LFE channel) are arrayed at roughly-equal intervals around the unit circle. Sophisticated applications may wish to allow the user to alter MSS's speaker positions to match the positions of the actual speakers that surround the listener. You can call AIL_set_speaker_configuration to submit an array of up to n speaker locations, where n is the number of logical channels in the configuration as reported by AIL_speaker_configuration. The submitted speaker locations will replace the default locations chosen at driver initialization time.

Almost all games will want to specify a falloff power greater than 1.0 to exaggerate the movement of sounds between speakers. At 1.0, MSS's 3D pan function is constant in power. A sound will not appear to grow louder or software as it moves around the listener, providing it remains equidistant. Higher falloff powers can make games sound more 'interesting' due to increased apparent movement of sound sources... but this effect comes at the expense of level accuracy, as the sound will not tend to be as loud when it's positioned between speakers. The examms example program can help you judge the effect of different falloff powers.

You can use AIL_set_speaker_configuration to change the falloff power without supplying new speaker locations. To do this, simply pass 0 for n_channels and NULL for array. MSS's default falloff power is 3.0.

How do stereo HSAMPLEs work in a multi-channel environment?

As noted above, stereo samples and streams are mapped to the FR/FL channels in an output mode with >= 2 channels, and combined for output in MSS_MC_MONO mode. In most applications that don't switch between first-person and third-person points of view, it usually doesn't make sense to enable 3D positioning on a stereo sample; the channels will be downmixed to mono at runtime, taking up extra memory space and CPU time. Stereo and multichannel samples don't work at all in DirectSound3D or EAX; you'll need to open a separate HDIGDRIVER to handle them.

Next Topic (What's the best way to port my older Miles application to MSS 7?)

Previous Topic (How do I play a digital sound?)

Group: FAQs and How Tos, Overview for Microsoft Xbox, The Digital Audio Pipeline
Related Sections: Creative's EAX 2 Properties, Creative's EAX 3 Properties, Creative's EAX 4 Properties, Sound under Win32, Sound under Win64
Related Functions: AIL_WAV_info, AIL_calculate_3D_channel_levels, AIL_init_sample, AIL_open_digital_driver, AIL_open_stream, AIL_quick_startup, AIL_sample_3D_position, AIL_sample_channel_count, AIL_sample_channel_levels, AIL_sample_output_levels, AIL_set_listener_3D_position, AIL_set_named_sample_file, AIL_set_sample_3D_cone, AIL_set_sample_3D_distances, AIL_set_sample_3D_orientation, AIL_set_sample_3D_position, AIL_set_sample_3D_velocity, AIL_set_sample_channel_levels, AIL_set_sample_file, AIL_set_sample_info, AIL_set_sample_volume_levels, AIL_set_sample_volume_pan, AIL_set_speaker_configuration, AIL_set_speaker_reverb_levels, AIL_speaker_configuration, AIL_speaker_reverb_levels
Related Basic Types: MSS_MC_SPEC, MSS_SPEAKER
Related Structures: AILSOUNDINFO
Related FAQs: What's the best way to port my older Miles application to MSS 7?


What's the best way to port my older Miles application to MSS 7?

Miles Sound System SDK 7.2a

Q:

What's the best way to port my older Miles application to MSS 7?

A:

The following notes apply specifically to the Win32 platform, but much of the same work will be needed on the other platforms supported by Miles as well. We don't change our API specs lightly -- some of this stuff has remained untouched since the Windows 3.1 days! But code, like fish, doesn't get better with age. We believe that the library has benefited enormously from the housecleaning work we've put into MSS 7. And in fact, most of the changes have the same goal -- to make it easier for application developers to integrate MSS.

Virtually all of the changes in MSS 7 have been specific to the digital audio portion of the library. The good news is that if your application uses only the core 2D digital audio functionality in MSS 6, you can upgrade to the new system with almost no effort at all. Here are the basic steps that MSS digital-audio applications will need to follow in order to migrate to MSS 7:

  • Change any remaining calls to the deprecated AIL_waveOutOpen and AIL_waveOutClose functions to AIL_open_digital_driver and AIL_close_digital_driver. If your application passed specific device IDs to the older functions, you will need to set the DIG_PREFERRED_WO_DEVICE and/or DIG_PREFERRED_DS_DEVICE preferences to those device IDs before calling AIL_open_digital_driver. You can still pass 1 or 2 as the channel parameter for AIL_open_digital_driver, but consider using an MSS_MC_SPEC enum value instead for multichannel support!

  • Change AIL_filter_sample_attribute and AIL_set_filter_sample_preference to AIL_sample_stage_property. Applications that use only one of the eight available per-sample filter slots should specify SP_FILTER_0 for the new calls' stage parameters.

  • If your application uses the Lagrangian interpolator filter, you should remove it. Similarly, the mono/stereo delay filters have been replaced with a single delay filter that can be used for both purposes.

  • Applications that use AIL_load_sample_buffer must now call AIL_start_sample themselves. Low-level streamed ("double-buffered") samples are no longer started automatically as soon as the first buffer is loaded. It's not necessary to check the status of a low-level streaming sample before calling AIL_start_sample -- if it's already playing, the call will be ignored.

  • Remove any calls to AIL_set_sample_type. The parameters formerly taken by AIL_set_sample_type have been moved to AIL_init_sample. It is not necessary to call AIL_init_sample prior to AIL_set_sample_file, AIL_set_named_sample_file, or AIL_set_sample_info.

  • Remove any calls to AIL_allocate_file_sample and AIL_register_EOF_callback. Use AIL_set_sample_file or AIL_set_named_sample_file instead.

  • We've removed a number of 'wrapper' functions that obscured the underlying HSAMPLE used by a DLS synthesizer or digital audio stream. These functions included AIL_DLS_set_reverb_levels, AIL_DLS_get_reverb_levels, AIL_stream_reverb_levels, AIL_set_stream_reverb_levels, AIL_DLS_processor, AIL_set_DLS_processor, AIL_stream_processor, AIL_set_stream_processor, AIL_stream_playback_rate, AIL_set_stream_playback_rate, AIL_set_stream_low_pass_cut_off, AIL_stream_low_pass_cut_off, AIL_set_stream_volume_pan, AIL_stream_volume_pan, AIL_filter_stream_attribute, AIL_set_filter_stream_preference, AIL_filter_DLS_attribute, and AIL_set_filter_DLS_preference. If your code uses any of these functions, you can replace them with calls to AIL_DLS_sample_handle and AIL_stream_sample_handle followed by the HSAMPLE-based version of the function you were calling.

If your application uses 3D sample handles, there's a bit more work ahead. The 3D and 2D digital audio subsystems -- and their associated data types -- have been combined in MSS 7. All of the 3D positioning calls can be used with ordinary HSAMPLES, rather than the specialized H3DSAMPLE type introduced with MSS 5.0 for 3D-positional samples. For the first time in MSS's history, you can use per-sample filters and play streaming audio, MP3/Ogg Vorbis files, or DLS sequences through EAX or DirectSound3D. The digital audio API is much cleaner now that it's no longer artificially divided into two incompatible halves. However, in the course of making these functional improvements, a number of significant changes to the 3D API emerged as necessary, desirable, or just plain overdue.

  • Instead of opening a 2D driver with AIL_open_digital_driver and a separate 3D driver with a call to AIL_open_3D_provider, your MSS 7 application will need to acquire its 3D audio resources by calling AIL_open_digital_driver with channels equal to the enumerated MSS_MC_SPEC value corresponding to the desired output provider or discrete-channel format. (See FAQ for an explanation of the available MSS_MC_SPEC options.)

  • AIL_enumerate_3D_providers, AIL_set_3D_provider_preference, AIL_enumerate_3D_provider_attributes, AIL_open_3D_provider, and AIL_close_3D_provider have been removed altogether. If your code formerly worked with provider-level 3D preferences or attributes, these are either obsolete now, or (in the DirectSound3D / EAX cases) accessible via the newly-added AIL_output_filter_driver_property function.

  • The H3DSAMPLE type has been removed. Use HSAMPLEs everywhere you previously used H3DSAMPLEs. Most functions that formerly operated on H3DSAMPLEs were removed, including AIL_3D_sample_attribute, AIL_3D_sample_length, AIL_3D_sample_loop_count, AIL_3D_sample_offset, AIL_3D_sample_playback_rate, AIL_3D_sample_status, AIL_3D_sample_volume, AIL_allocate_3D_sample_handle, AIL_end_3D_sample, AIL_register_3D_EOS_callback, AIL_release_3D_sample_handle, AIL_resume_3D_sample, AIL_set_3D_sample_info, AIL_set_3D_sample_loop_block, AIL_set_3D_sample_loop_count, AIL_set_3D_sample_offset, AIL_set_3D_sample_playback_rate, AIL_set_3D_sample_preference, AIL_set_3D_sample_volume, AIL_start_3D_sample, AIL_stop_3D_sample, and AIL_3D_sample_count. Your application will need to move to the HSAMPLE-based versions of each of these functions.

  • Code that previously used AIL_3D_sample_attribute and AIL_set_3D_sample_preference will need to use AIL_sample_stage_property with the SP_OUTPUT stage identifier instead. Note also that AIL_3D_sample_offset's HSAMPLE-based equivalent is AIL_sample_position -- which is distinct from AIL_sample_3D_position!

  • Calls to AIL_set_3D_sample_effects_level should be replaced with AIL_set_sample_reverb_levels. The new function allows you to specify per-sample wet and dry levels separately. Per-sample wet level defaults to 0.0, so you must call AIL_set_sample_reverb_levels with a non-zero wet level for any HSAMPLE that needs to undergo reverb processing. As in previous versions of MSS, EAX applications must call AIL_set_digital_master_reverb_levels to set the master wet level to 0.0 explicitly if no enviromental processing is desired in the default ENVIRONMENT_GENERIC room type. This is a notable difference between the per-voice hardware providers and software mixer's behavior; in software, ENVIROMENT_GENERIC is completely dry.)

  • AIL_set_sample_3D_distances now takes a third parameter, auto_3D_wet_atten, which determines whether or not reverb effects are attenuated with distance and cone direction. Applications should set this parameter to a nonzero value to emulate the old system's behavior with EAX 2, EAX 3, and EAX 4.

  • The H3DPOBJECT type has been removed, as well as the AIL_auto_update_3D_position, AIL_open_3D_listener, AIL_close_3D_listener, AIL_open_3D_object, AIL_close_3D_object, AIL_3D_user_data, and AIL_set_3D_user_data functions. The remaining functions which took H3DPOBJECTs, including AIL_3D_orientation, AIL_3D_position, AIL_3D_velocity, AIL_3D_velocity_vector, AIL_set_3D_orientation, AIL_set_3D_position, AIL_update_3D_position, AIL_set_3D_velocity, and AIL_set_3D_velocity_vector have been replaced with versions specific to HSAMPLEs (AIL_sample_3D_orientation, AIL_sample_3D_position, AIL_sample_3D_velocity, AIL_set_sample_3D_orientation, AIL_set_sample_3D_position, AIL_set_sample_3D_velocity, AIL_set_sample_3D_velocity_vector) and HDIGDRIVERs (AIL_listener_3D_orientation, AIL_listener_3D_position, AIL_listener_3D_velocity, AIL_set_listener_3D_orientation, AIL_set_listener_3D_position, AIL_update_listener_3D_position, AIL_set_listener_3D_velocity, AIL_set_listener_3D_velocity_vector).

  • Similarly, the functions AIL_set_3D_distance_factor, AIL_set_3D_doppler_factor, AIL_set_3D_rolloff_factor, AIL_set_room_type, AIL_3D_distance_factor, AIL_3D_doppler_factor, AIL_3D_rolloff_factor, and AIL_room_type now take an HDIGDRIVER rather than an HPROVIDER.

  • AIL_set_3D_room_type and AIL_3D_room_type have been renamed to AIL_set_room_type and AIL_room_type, respectively. These functions are available even for samples that aren't undergoing 3D positioning by MSS. Likewise, AIL_set_3D_sample_occlusion, AIL_set_3D_sample_obstruction, AIL_set_3D_sample_exclusion, AIL_3D_sample_occlusion, AIL_3D_sample_obstruction, and AIL_3D_sample_exclusion have been renamed to AIL_set_sample_occlusion, AIL_set_sample_obstruction, AIL_set_sample_exclusion, AIL_sample_occlusion, AIL_sample_obstruction, and AIL_sample_exclusion.

  • The remaining AIL_(set_)3D_sample...() and AIL_(set_)3D_listener...() functions have been renamed to AIL_(set_)sample_3D...() and AIL_(set_)listener_3D...() to reflect the fact that 3D positioning is now just another property of an HSAMPLE or HDIGDRIVER, rather than a feature implemented by a distinct '3D sample' or '3D listener' type.

  • Note that an HSAMPLE's 3D properties are ignored by MSS's software mixer until the application requests 3D positioning support by calling AIL_set_sample_3D_position! Once enabled for a given HSAMPLE, 3D positioning can be disabled by releasing and reallocating the HSAMPLE, or by calling AIL_init_sample, AIL_set_sample_file, AIL_set_named_sample_file, or AIL_set_sample_info. Again, environmental effects such as reverb, occlusion, obstruction, and exclusion do not depend on a sample's 3D positional status; in MSS 7, only the functions whose names contain '3D' are involved with position and orientation in 3D space.

  • The AIL_set_3D_speaker_type function and the MILES_SPEAKER_TYPE definitions have been removed. Speaker types are either specified by the end user via their Windows control panel or OEM configuration applet, or are implicit in the MSS channel specification passed to AIL_open_digital_driver (e.g., MSS_MC_51_DISCRETE or MSS_MC_STEREO).

Attributes and preferences were merged into one concept called properties. Properties cover the functionality of both attributes and preferences and can be read and written to in one function call. To port old code that queried attributes, you usually just have to change the function call into the property version and pass the address of a receiving variable. For example, code such as

value = AIL_sample_filter_attribute(S,"name,")

would become

AIL_sample_filter_property(S,"name",&value,0,0)

Porting old code that set a preference is even easier - just change from

AIL_set_sample_filter_preference(S,"name",&value)

to

AIL_sample_filter_property(S,"name",0,&value,0)

.

Next Topic (How do I play an XMIDI or MIDI file?)

Previous Topic (How do I use multi-channel sound output in Miles?)

Group: FAQs and How Tos
Related Functions: AIL_3D_distance_factor, AIL_3D_doppler_factor, AIL_3D_rolloff_factor, AIL_DLS_sample_handle, AIL_close_digital_driver, AIL_init_sample, AIL_listener_3D_orientation, AIL_listener_3D_position, AIL_listener_3D_velocity, AIL_load_sample_buffer, AIL_open_digital_driver, AIL_output_filter_driver_property, AIL_room_type, AIL_sample_3D_orientation, AIL_sample_3D_position, AIL_sample_3D_velocity, AIL_sample_exclusion, AIL_sample_obstruction, AIL_sample_occlusion, AIL_sample_position, AIL_sample_stage_property, AIL_set_3D_distance_factor, AIL_set_3D_doppler_factor, AIL_set_3D_rolloff_factor, AIL_set_digital_master_reverb_levels, AIL_set_listener_3D_orientation, AIL_set_listener_3D_position, AIL_set_listener_3D_velocity, AIL_set_listener_3D_velocity_vector, AIL_set_named_sample_file, AIL_set_room_type, AIL_set_sample_3D_distances, AIL_set_sample_3D_orientation, AIL_set_sample_3D_position, AIL_set_sample_3D_velocity, AIL_set_sample_3D_velocity_vector, AIL_set_sample_exclusion, AIL_set_sample_file, AIL_set_sample_info, AIL_set_sample_obstruction, AIL_set_sample_occlusion, AIL_set_sample_reverb_levels, AIL_start_sample, AIL_stream_sample_handle, AIL_update_listener_3D_position
Related Basic Types: MILES_PREFERENCES, MSS_MC_SPEC
Related FAQs: How do I use multi-channel sound output in Miles?


How do I play an XMIDI or MIDI file?

Miles Sound System SDK 7.2a
Q: | How do I play an XMIDI or MIDI file?
A: | To play an XMIDI file, follow these steps: 1) Allocate an HSEQUENCE with AIL_allocate_sequence_handle. 2) Load the file from the disk with AIL_file_read (or your own file IO routines). 3) Call AIL_init_sequence to point the HSEQUENCE at the loaded disk file image. 4) Play the file with AIL_start_sequence. To play a standard MIDI file, call the AIL_MIDI_to_XMI function to convert the MIDI file into an XMIDI file image and then follow the XMIDI steps.

Next Topic (How do I play an XMIDI file with a DLS instrument set?)

Previous Topic (What's the best way to port my older Miles application to MSS 7?)

Group: FAQs and How Tos
Related Functions: AIL_MIDI_to_XMI, AIL_allocate_sequence_handle, AIL_file_read, AIL_init_sequence, AIL_start_sequence
Related FAQs: How do I play an XMIDI file with a DLS instrument set?


How do I play an XMIDI file with a DLS instrument set?

Miles Sound System SDK 7.2a
Q: | How do I play an XMIDI file with a DLS instrument set?
A: | To play an XMIDI file using a DLS instrument set, follow these steps: 1) Open the DLS synth with AIL_DLS_open. 2) Load the instrument set from the disk with AIL_file_read. 3) Use AIL_extract_DLS to uncompress the instrument set, if necessary. You call tell if you need to uncompress the file by checking the type of the file with the AIL_file_type function. 4) Load the instrument set into the synthesizer with AIL_DLS_load_memory. 5) Now follow the steps in the "How do I play a MIDI file?" FAQ.

Next Topic (How do I stream a file off a hard disk or CD?)

Previous Topic (How do I play an XMIDI or MIDI file?)

Group: FAQs and How Tos
Related Functions: AIL_DLS_load_memory, AIL_DLS_open, AIL_extract_DLS, AIL_file_read, AIL_file_type
Related FAQs: How do I play an XMIDI or MIDI file?


How do I stream a file off a hard disk or CD?

Miles Sound System SDK 7.2a
Q: | How do I stream a file off a hard disk or CD?
A: | To stream a digital sound off the disk, follow these steps: 1) Open the file to stream with AIL_open_stream. 2) Play the stream with AIL_start_stream.

Next Topic (How do I play a track off a CD?)

Previous Topic (How do I play an XMIDI file with a DLS instrument set?)

Group: FAQs and How Tos
Related Functions: AIL_open_stream, AIL_start_stream


How do I play a track off a CD?

Miles Sound System SDK 7.2a
Q: | How do I play a track off a CD?
A: | To play a CD track, follow these steps: 1) Open the redbook device with AIL_redbook_open. 2) Get the start and stop points with AIL_redbook_track_info. 3) Call AIL_redbook_play to begin playing the track.

Next Topic (How do I loop a track off a CD?)

Previous Topic (How do I stream a file off a hard disk or CD?)

Group: FAQs and How Tos
Related Functions: AIL_redbook_open, AIL_redbook_play, AIL_redbook_track_info


How do I loop a track off a CD?

Miles Sound System SDK 7.2a

Q:

How do I loop a track off a CD?

A:

To loop a CD track, you have to do a little more work, because you can't instruct the hardware itself to loop. To handle this, follow these steps:

1) Open the redbook device with AIL_redbook_open.

2) Get the start and stop points with AIL_redbook_track_info.

3) Call AIL_redbook_play to begin playing the track.

4) Subtract the starting and stopping points to calculate the length of the track, and then add a second or two of slop time.

5) Create a timer (system or Miles) for the length of time of the song.

6) Restart the CD track when the timer expires (and reset your timer for the next loop).

Next Topic (I used an older version of Miles and now my volume and pan calls are weird - what's going on? And what's with the two types of volume functions?)

Previous Topic (How do I play a track off a CD?)

Group: FAQs and How Tos
Related Functions: AIL_redbook_open, AIL_redbook_play, AIL_redbook_track_info


I used an older version of Miles and now my volume and pan calls are weird - what's going on? And what's with the two types of volume functions?

Miles Sound System SDK 7.2a

Q:

I used an older version of Miles and now my volume and pan calls are weird - what's going on? And what's with the two types of volume functions?

A:

Miles 6.5 introduced new floating point volume functions. These functions give you much finer control than the old MIDI compatible (0 to 127) range functions.

You should search your application for all calls to the old Miles digital volume functions (AIL_set_sample_volume and AIL_set_stream_volume) and update them to use the new 0 to 1.0 floating point scale instead of the old 0 to 127 integer scale.

And, since we were breaking the API somewhat for this new functionality, we added some extra features as well. We now give you two ways to control volume - one based on the human perception loudness scale, and one based on a linear reduction of the sound's amplitude.

If you use AIL_set_sample_volume_pan to set the volume, then a 0.5 value means that the audio will "sound" half as loud to you (this means the sound is 10 dB down).

If, on the other hand, you use the AIL_set_sample_volume_levels function, then a 0.5 value means that the audio's actual numeric sample values will be cut in half (this means the sound is only 6 dB down).

Also note that AIL_set_sample_volume_pan now uses a power-pan calculation for the left to right setting. Power-pan means that we vary both the left-to-right mix and the absolute volume to make the total power coming out of your speakers relatively constant. So, now when you pan a sound from left to right, it won't sound louder when the audio is directly in the center.

Conversely, the AIL_set_sample_volume_levels function allows you to specify the left and right volumes directly, so you can implement any type of pan that you like.

For mono samples that will undergo 3D positioning, you should use a pan value of 0.5. Any other pan value will cause the 3D positioner to favor one speaker or the other in each successive multichannel pair.

Note that in MSS 7, several volume-control calls that were just 'wrappers' on HSAMPLES internal to streams and DLS sequences were removed. You can use the HSAMPLE-based volume calls for these data types in conjunction with AIL_stream_sample_handle and AIL_DLS_sample_handle.

As an aside, internally, the AIL_set_sample_volume_pan function just does some calculations and then calls the AIL_set_sample_volume_levels function.

Next Topic (What kind of audio decompression does Miles support?)

Previous Topic (How do I loop a track off a CD?)

Group: FAQs and How Tos
Related Functions: AIL_DLS_sample_handle, AIL_sample_volume_levels, AIL_sample_volume_pan, AIL_set_sample_volume_levels, AIL_set_sample_volume_pan, AIL_stream_sample_handle


What kind of audio decompression does Miles support?

Miles Sound System SDK 7.2a

Q:

What kind of audio decompression does Miles support?

A:

Miles supports IMA ADPCM, MP3 (MPEG Layer 3), Ogg Vorbis, Voxware voice, Sony PS2 VAG, Xbox ADPCM hardware, and Xbox 360 XMA decompression.

IMA ADPCM is a simple format that provides 4 to 1 compression on 16-bit data. There is essentially no CPU hit for decoding ADPCM - it's that simple. Like all ADPCM variants, it is somewhat hissy, though.

MP3 (or MPEG Layer 3) is a more complicated format that usually provides 11 to 1 compression with no audible loss. It does use a bit more CPU, though. See the "What is MPEG Audio and MP3?" FAQ for more details about MP3. You need to sign a special license addendum to use MP3.

Ogg Vorbis is an non-patented MP3 alternative, with similar capabilities and limitations. It does use about twice the CPU of MP3, so it is the most expensive of our codecs. At low bit rates (128 kbit or less), Ogg usually sounds a little better than MP3. At higher bit rates, you can't tell the difference, so you are better off using MP3 due to the lower CPU hit. You also need to sign a special license addendum to use Ogg Vorbis.

The Voxware voice codecs are complicated formats that provide up to 200 to 1 compression on voice data (fairly compressed-sounding, though). They are only for voice data, though - they can't do anything at all with music or sound effects. The Voxware codecs are used almost exclusively for Internet voice chat.

On the original Xbox, Miles can also play Xbox ADPCM with no CPU hit at all - it is transparently decoded in hardware. These files can only be played on an original Xbox, though.

On the Xbox 360, Miles can play XMA files. XMA is a perceptual encoder like MP3 and Ogg, but not quite as powerful. It can be decompressed mostly in hardware, so it's only a little slower than IMA ADPCM, though. It's a great option on the Xbox 360, but it can't be played on any other platform.

On the PS2, you can use the RAD_IOP API to play VAG files in hardware with no CPU hit. VAG files are a Sony version of ADPCM. It's a good option for the usually CPU-constrained PS2.

Next Topic (What is MPEG Audio and MP3?)

Previous Topic (I used an older version of Miles and now my volume and pan calls are weird - what's going on? And what's with the two types of volume functions?)

Group: FAQs and How Tos
Related FAQs: What is MPEG Audio and MP3?


What is MPEG Audio and MP3?

Miles Sound System SDK 7.2a

Q:

What is MPEG Audio and MP3?

A:

MPEG audio is a standard that was created to compress the audio streams that accompany MPEG video streams. Because it was invented almost 8 years ago, MPEG audio needed to be scalable in playback complexity. The MPEG group, therefore, came up with three levels of compression complexity: MPEG Layer 1, MPEG Layer 2, and MPEG Layer 3. Each level provided almost twice the audibly lossless compression ratio (MP1 provides 3 to 1, MP2 provides 6 to 1, and MP3 provides 11 to 1), but each level required more and more CPU horsepower.

However, now, 8 years later, even the sophisticated Layer 3 compression standard only uses a small percentage of the total power of a modern desktop CPU. This means we can now take advantage of the massive size savings that MPEG Layer 3 can provide! For example, at the usual compression ratio of 11 to 1, this means you could store up to 13.5 hours of audio on one CD! And remember, this is audibly lossless compression - you can't hear any difference!

Before MSS, one bad aspect to using MP3 compression was the fact that two overseas companies owned the compression and decompression patent rights to the MP3 algorithm. That meant that if you wanted to add MP3 to your commercial product, then you had to go through a convoluted and lengthy licensing process to obtain an expensive license. Worse, you were simply paying for the patent rights - you still had to write the MP3 decoder itself!

However, with the Miles Sound System, we have arranged through Fraunhofer and Thomson multimedia to provide a legally redistributable MP3 decoder for no extra cost! You must sign an extra MPEG license addendum (which, among other minor things, requires you to add a credit to Fraunhofer and Thomson in your game), but, other than that, you can use MP3 decompression just like our already built-in IMA ADPCM decompression. More about that in a minute, though.

Now, MPEG Layer 3 encoding is a completely different situation. RAD does sell an MPEG Layer 3 encoder, but does so completely separately from the Miles Sound System. This MP3 encoder is available from us on a per-machine basis for $95.00. Note that you cannot redistribute this encoder - it is for your use only. To obtain a redistributable encoder, give us a call and we can get you in touch with the right people at Fraunhofer.

The Miles MP3 encoder is based on the ISO reference source code. This means that while the sound quality of the compression is very good, the compression speed is very, very slow. It can take up to 5 minutes to compress a single 3 minute WAV file! The ISO reference source also has one other limitation - it can only compress 32 Khz, 44 Khz, and 48 Khz data rates. That means that if you try to compress a 22 Khz input file, the Miles encoder will upsample it to 32 Khz and then compress it (which obviously hurts the overall compression ratio).

Because of these limitations, you may want to look at alternative MP3 compressors - this is a highly competitive field and there are many very good, very fast MP3 encoders available (including ones that support other sample rates - 16, 22 and 24 Khz). See the MP3.COM web site for links to many different encoders. The Fraunhofer encoders are generally found to be the very best (and are relatively inexpensive).

One feature that the other encoders don't have, however, is the ability to compress the instruments in a DLS file. Only the Miles MP3 encoder can currently perform this specific type of compression (which can compress DLS files up to 11 to 1). With this feature, the Miles MP3 encoder can give you incredibly small digital music files. For example, on our web site are several DLS files that are under 1 MB is size, yet contain 7 to 10 MBs of instrument data!

OK, now let's talk about the Miles MP3 decoder. First off, the Miles MP3 decoder is just that: an MP3 decoder. Miles cannot decode or playback MPEG Layer 1 or MPEG Layer 2 compressed audio. You must uncompress data compressed with the simpler formats with a non-Miles utility, and then recompress it using MP3. However, since MP3 is 4 times as small as MP1 and 2 times as small as MP2, this should be to your advantage once the data is converted.

Once the Miles MP3 decoder is installed, MP3 data is treated like a completely integrated sound type - the data doesn't even have to be decompressed before passing it to Miles! However, the MP3 decompression process does take more CPU than the comparatively simple IMA ADPCM algorithm.

To solve this problem, Miles also allows you to pre-decompress MP3 data. This way, if CPU-performance is critical, then you can decompress the MP3 files ahead of time (say when you load the game level data). If, however, memory is critical and CPU-performance isn't important, then you could decompress all of the MP3 files on the fly. The choice is up to you!

Since an MPEG Layer 3 file contains just the compressed data (MP3 files don't really have an identifying header), you must use a new function called AIL_set_named_sample_file to tell Miles that it is dealing with MP3-compressed data. There is one exception to this - Microsoft has defined a special type of WAV file that can contain MP3 data (basically the MP3 data is wrapped up into a RIFF chunk).

If you use this weird WAV file format, then Miles can use the same old AIL_set_sample_file function that you've always used to load sound data. However, not all encoders (including the Miles MP3 encoder) support this WAV file wrapping system, so most of the time you should use the new AIL_set_named_sample_file function (which works with either type of MP3 file).

Next Topic (What MP3 encoder should I use?)

Previous Topic (What kind of audio decompression does Miles support?)

Group: FAQs and How Tos
Related Functions: AIL_set_named_sample_file, AIL_set_sample_file
Related FAQs: What kind of audio decompression does Miles support?


What MP3 encoder should I use?

Miles Sound System SDK 7.2a

Q:

What MP3 encoder should I use?

A:

The encoders are being upgraded so quickly that it's hard to give a recommendation that will be valid for any length of time.

We've generally found the Fraunhofer encoders to be the best (and are relatively inexpensive) - after all, they did first publish the format!

If you want to compress the DLS instruments in your files, then you need our encoder - it is the only one with the hooks necessary to encode DLS files. Our encoder isn't the best for general MP3 encoding, though.

If you will be doing looping or seeking of any type on MP3 files, they'll sound much better if you encode them without using the format's bit-reservoir feature. With the LAME encoder (also among the best available), the command-line option --nores will ensure that all of the source data associated with an MP3 frame is stored within the physical boundaries of the frame.

The MAKELOOP.EXE utility is a Win32 console application that works in conjunction with LAME to create loopable .MP3 and ADPCM .WAV files. It will accept PCM .WAV, ADPCM .WAV, or existing .MP3 files as input. When encoding MP3 files, MAKELOOP.EXE resamples your input file to the next-smaller multiple of the MP3 frame size (usually 1152 samples), then launches LAME with a combination of options chosen for loop-transition quality. Finally, MAKELOOP.EXE post-processes LAME's output file to remove silent frames.

MAKELOOP.EXE is especially convenient because you don't need to specify subblock offsets with AIL_set_sample_loop_block or AIL_set_stream_loop_block to loop a file encoded by it. Just use AIL_set_sample_loop_count or AIL_set_stream_loop_count to loop the entire file. Most loopable .WAV files will sound great when encoded with MAKELOOP.EXE, saving your production department the need to select and audition loop points manually with the Miles Sound Player.

You can run MAKELOOP.EXE with no command-line options to see usage notes for the current version. Most .WAV files can be encoded simply by running makeloop infile.wav outfile.mp3.

Next Topic (I can't get Miles to play an MP3, XMA, or Ogg Vorbis file - what's going on?)

Previous Topic (What is MPEG Audio and MP3?)

Group: FAQs and How Tos
Related Functions: AIL_set_sample_loop_block, AIL_set_sample_loop_count, AIL_set_stream_loop_block, AIL_set_stream_loop_count


I can't get Miles to play an MP3, XMA, or Ogg Vorbis file - what's going on?

Miles Sound System SDK 7.2a

Q:

I can't get Miles to play an MP3, XMA, or Ogg Vorbis file - what's going on?

A:

If you can't play an MP3, Ogg Vorbis, or similar file, try these troubleshooting questions:

1) Did you copy all the redistribution files into a directory available to your application? Are they up to date with the version of Miles that you're using?

2) On Win32, Win64, MacOS and Linux, did you call AIL_set_redist_directory to tell Miles where this directory is? This directory is relative to the location of the Miles library file, so if you are using a relative path - make sure it is relative to the right directory!

2) On platforms that don't support x86 (Win32) DLLs, did you call Register_RIB(MP3Dec) to tell Miles to load the MP3 decoder, Register_RIB(OggDec) to load the Ogg Vorbis decoder, or Register_RIB(XMADec) to load the Xbox 360 XMA decoder?

3) Are you using AIL_set_named_sample_file to tell Miles what type of data it is?

4) Did you sign the license agreements for MP3 and/or Ogg Vorbis decoding? This is a separate license addendum that your company might have chosen not to sign. Look for the ASI codec library files (*.ASI in Win32 and Win64) in the redistribution directory - are they present?

5) Is the file in question a true MP3 file? Miles doesn't play MPEG Layer 1 or MPEG Layer 2 files which are often mistakenly labeled MP3 files. Try recompressing the file yourself just to be sure.

Next Topic (How can I lower the CPU hit of playing an MP3 file?)

Previous Topic (What MP3 encoder should I use?)

Group: FAQs and How Tos
Related Functions: AIL_set_named_sample_file, AIL_set_redist_directory


How can I lower the CPU hit of playing an MP3 file?

Miles Sound System SDK 7.2a

Q:

How can I lower the CPU hit of playing an MP3 file?

A:

The Miles MP3 decoder is amazingly fast - we have Intel x87, Intel SSE, AMD 3DNow, PowerPC and MIPS assembly optimized versions. On a modern PC, you can play 32 44 Khz stereo MP3 files using about 12% of the CPU. On a Mac, 32 samples use about 25%. On an Xbox 360, 32 samples use 19%. On a slower platform like PS/2, one MP3 sample takes about 8% of the CPU.

You can cut the CPU hit almost linearly by dropping the sample rate, and/or the number of channels. For example, 44 Khz mono takes as little as 1.5%.

In general, we've seen very few places where the CPU hit of MP3 is a problem. Remember that if you are streaming audio in off a drive, you usually take a larger CPU hit just in I/O overhead (which MP3 will help because you are reading a tenth as much data).

Next Topic (I'm getting a glitch when I loop an MP3 or ADPCM file - what can I do?)

Previous Topic (I can't get Miles to play an MP3, XMA, or Ogg Vorbis file - what's going on?)

Group: FAQs and How Tos


I'm getting a glitch when I loop an MP3 or ADPCM file - what can I do?

Miles Sound System SDK 7.2a

Q:

I'm getting a glitch when I loop an MP3 or ADPCM file - what can I do?

A:

Short answer: Use MAKELOOP.EXE to encode any .MP3 or ADPCM .WAV files that need to be looped at runtime.

The MAKELOOP.EXE utility is a Win32 console application that creates loopable IMA ADPCM .WAV files or, in conjunction with the LAME command-line encoder, loopable .MP3 files. It will accept PCM .WAV, ADPCM .WAV, or existing .MP3 files as input.

MAKELOOP.EXE works by decimating your input file, or resampling it to conform to the next-smaller multiple of the encoded frame size. Frame sizes are typically very small -- on the order of 1000-4000 samples for ADPCM files and 1152 samples for MP3 files -- so this resampling process does not usually cause a large change in the pitch of the encoded sample. Next, MAKELOOP.EXE prepends a copy of the last frame in the file to the beginning of the file. This makes the file appear to be a continuous stream from the encoder's point of view, with the goal of preventing mismatches between ADPCM block initializers and MP3 overlap-window contents when the file is looped at runtime. The file is then compressed with either the LAME command-line encoder or the AIL_compress_ADPCM function, depending on the specified output file suffix. MP3 files are encoded with the --nores option to further reduce interframe dependencies. Finally, MAKELOOP.EXE post-processes the encoded output file to remove unnecessary frames, including silent and metadata frames added by LAME and the copy of the final frame that was prepended earlier.

MAKELOOP.EXE is especially convenient because you don't need to specify subblock offsets with AIL_set_sample_loop_block or AIL_set_stream_loop_block to loop a file encoded by it. Just use AIL_set_sample_loop_count or AIL_set_stream_loop_count to loop the entire file. Most loopable .WAV files will sound great when encoded with MAKELOOP.EXE, saving your production department the need to select and audition loop points manually with the Miles Sound Player (below).

You can run MAKELOOP.EXE with no command-line options to see usage notes for the current version. Most .WAV files can be encoded simply by running makeloop infile.wav outfile.mp3 to generate an .MP3 output file or makeloop infile.wav outfile.wav to generate an ADPCM .WAV file.

Long answer: A number of things can go wrong when trying to loop or seek within an MP3 file or stream. Fundamentally, MP3 decoding is a DSP-intensive process that uses discrete mathematical transforms to operate on continuous real-world data -- which is itself partitioned into discrete frames! What that means is that MP3 frames can't be interpreted in a vacuum. To decode a given frame properly, the decoder must overlap its data with data left over from the previous frame. Worse, using an entirely-unrelated feature called the bit reservoir, MP3 files can 'borrow' space needed to store data for a particular frame from several of the preceding frames!

These two factors make it unlikely that an arbitrary attempt to seek from one part of an MP3 file to another will be free of objectionable artifacts. In MSS version 7, we've introduced a handy utility as part of the Miles Sound Player application that will help you find glitch-free loop points in almost any given MP3 file. Several commercial sound editors will display the frame-boundary offsets within an MP3 file, but only the Miles Sound Player lets you place loop points and 'audition' them with the assurance that they'll sound the same in your own application!

After loading an MP3 or ADPCM file (or any other supported digital audio file), you can use the Pause/Play button to stop playback, then zoom in with the mouse wheel if necessary to reveal the frame boundaries. Left-click in the waveform display to place a green marker that designates the beginning of a loop; right-click to place the red end-of-loop marker. (An existing loop may be removed by clicking on one of its markers.) With a valid loop selection, playback will be constrained to the looped region the next time you hit Pause/Play. You'll be able to hear any artifacts resulting from gross mismatches in the overlap window and/or bit-reservoir contents between the boundary frames.

Any calls to AIL_set_sample_position, AIL_set_stream_position, or AIL_set_sample_loop_block with MP3 source data should specify offsets that lie on frame boundaries. This helps us avoid mistakenly interpreting intraframe data as a valid frame boundary, making a bad glitching problem worse. The loop boundaries displayed by the Miles Sound Player are suitable for passing directly to AIL_set_sample_position, AIL_set_stream_position, or AIL_set_sample_loop_block. Note that MSS considers offset 0 to be the first byte after any ID3v2 tag or other metadata at the beginning of an MP3 file! Frame offsets reported by other MP3 editors will most likely be relative to the beginning of the entire file, making them unsuitable for use with the Miles API.

Looping an entire MP3 file image by setting AIL_set_sample_loop_count on the HSAMPLE (or AIL_set_stream_loop_count on an HSTREAM) is still a bit tricky. The reason is that most MP3 encoders -- if not all of them -- write varying amounts of silent information at the end of the MP3 files they generate. Some also add silence to the beginning of the file. Consequently, even if you take pains to make your source sample data phase-continuous across a multiple of the MP3 frame size, you will still find that a looped file exhibits a brief dropout at the loop point. Because any arbitrary sequence of adjacent frames is a perfectly-valid MP3 file, though, you can use the 'Save portion' button in the Miles Sound Player to write the selected looped portion of the file to a separate .MP3 file. The resulting file, if looped, will sound the same as the original subblock loop in the file it came from. So you can either write down the selected frame boundaries and use AIL_set_sample_loop_block on the original file, or save only the looped portion to a separate file which is looped in its entirety.

There's not much you can do about overlapped frame data other than to experiment to find 'loop-compatible' frames in the Miles Sound Player. However, the bit reservoir feature can be disabled with certain MP3 encoders, among them the popular open-source LAME (Lame Ain't an MP3 Encoder) package. We strongly recommend using the --nores option with LAME to encode any files that will undergo looping or seeking; it makes a big difference!

As a convincing demonstration, you can actually loop a pure sinewave with no audible glitches using the --nores option and a carefully-chosen frequency that's phase-continuous at the frame boundaries being looped. For 48 kHz, 44.1 kHz, and 32 kHz files, there are 1152 samples per MP3 frame. At all other rates, there are 576. For example, 64 complete cycles of a 2450-Hz sine wave encoded at 44100 Hz will occupy exactly 1152 samples. Each cycle takes 18 samples, and 18 is exactly 1152 / 64. If you encode a 44 kHz MP3 file with a sinewave at this frequency, using the LAME encoder's --nores option, you can use the Miles Sound Player to select any pair of intact frames in the file. The resulting loop will have no audible discontinuities! (To test this principle, try running the Miles Sound Player or the streamer.exe example program on loopable.mp3 in the media directory for a test. This file was created by encoding a 2450-Hz sine wave with LAME --nores and saving its middle frames with the Miles Sound Player's 'Save Portion' feature.)

With ADPCM files, it's very rarely necessary to experiment with loop points -- just use MAKELOOP.EXE instead. (Again, though, note that the only musically-pure tone that can be looped automatically is one whose period is an integral number of cycles between frame boundaries. This is true in both MP3 and ADPCM.)

Next Topic (How do I apply a low-pass filter?)

Previous Topic (How can I lower the CPU hit of playing an MP3 file?)

Group: FAQs and How Tos
Related Sections: Miles Sound Player
Related Functions: AIL_compress_ADPCM, AIL_set_sample_loop_block, AIL_set_sample_loop_count, AIL_set_sample_position, AIL_set_stream_loop_block, AIL_set_stream_loop_count, AIL_set_stream_position


How do I apply a low-pass filter?

Miles Sound System SDK 7.2a

Q:

How do I apply a low-pass filter?

A:

A low-pass filter attenuates frequencies over a specified cutoff frequency. Miles has a low-pass filter built directly into its mixer.

To set a low-pass filter on a sample, use AIL_set_sample_low_pass_cut_off.

To set a low-pass filter on a stream or DLS sequence, call AIL_stream_sample_handle or AIL_DLS_sample_handle and use the resulting HSAMPLE with AIL_set_sample_low_pass_cut_off.

Finally, you can also use the AIL_set_sample_occlusion function to simulate low-pass occlusion effects. EAX 2 (and later) 3D providers can perform occlusion filtering in hardware. In software-mixing contexts, the AIL_set_sample_low_pass_cut_off function is used to implement occlusion, so the two functions cannot be used together on the same HSAMPLE.

Next Topic (How do I set a DSP filter on a sample?)

Previous Topic (I'm getting a glitch when I loop an MP3 or ADPCM file - what can I do?)

Group: FAQs and How Tos
Related Functions: AIL_DLS_sample_handle, AIL_set_sample_low_pass_cut_off, AIL_set_sample_occlusion, AIL_stream_sample_handle


How do I set a DSP filter on a sample?

Miles Sound System SDK 7.2a

Q:

How do I set a DSP filter on a sample?

A:

To set a DSP filter, you have to first find the filter(s) that you want to apply. To find a filter, you can either enumerate through the possible filters looking for the one you want (using the AIL_enumerate_filters function), or you can use the simple utility function AIL_find_filter. For example, to find the high-pass DSP filter, do something like this:

Register_RIB(DSP);   // Needed on non-Win32 DLL platforms such as DOS, Xbox, Wii, PS2 and PS3
AIL_startup();
...
...
...
HPROVIDER high_pass;
if ( AIL_find_filter( "HighPass Filter", &high_pass ) )
{
  // success!
}

Once we have a handle to the high-pass filter, we have to apply it to our HSAMPLE with the AIL_set_sample_processor function. Eight filter slots, labelled SP_FILTER_0 through SP_FILTER_7, are available:

// init the sample
AIL_init_sample( S, DIG_F_MONO_16, 0 );

//later, apply the filter
AIL_set_sample_processor( S, SP_FILTER_0, high_pass );

Make sure you call AIL_set_sample_processor after you call AIL_init_sample, AIL_set_sample_file, AIL_set_sample_info, or AIL_set_named_sample_file. Filters may be assigned in any order, and it's OK to skip slots altogether. Filters assigned to lower-numbered slots are executed prior to those in higher-numbered ones.

Now, all that remains is setting the specific filter properties that you'd like to control. To do that, call the AIL_sample_stage_property function with one of the properties described in the Digital Filter Services Section. To finish our example, let's set the high-pass filter to kick in at 4000 Hz, like this:

F32 value=4000.0F;
AIL_sample_stage_property( S, SP_FILTER_0, "Highpass Cutoff", &value, 0, 0 );

Again, in most cases, you should install any DSP filters after declaring an HSAMPLE's format, but before starting playback. Installing or removing a DSP pipeline filter on a playing HSAMPLE may cause audible artifacts. To disable an existing filter's influence on a given HSAMPLE without uninstalling the filter, set the filter's "Mix' preference (if available) to 0.0.

Software DSP filters may be unsuitable for performance-critical applications on the original Xbox; the Xbox has specific dedicated DSP hardware that you may wish to use instead. Software DSP filters on the Xbox cannot be applied to Xbox ADPCM samples or 8-bit PCM samples.

See the FILTER.CPP and MULTIFLT.CPP example programs for more information.

Next Topic (How much CPU do the various filters use?)

Previous Topic (How do I apply a low-pass filter?)

Group: FAQs and How Tos
Related Functions: AIL_enumerate_filters, AIL_find_filter, AIL_init_sample, AIL_sample_stage_property, AIL_set_named_sample_file, AIL_set_sample_file, AIL_set_sample_info, AIL_set_sample_processor


How much CPU do the various filters use?

Miles Sound System SDK 7.2a

Q:

How much CPU do the various filters use?

A:

The built-in filters are very fast!

The built-in global reverb is about as expensive as mixing each sample twice (which is basically free - mixing 64 samples on a modern PC only costs about 1.5% of the CPU).

The built-in low-pass filter is also almost free - on a modern PC, you can low-pass filter 64 samples in less than 2% of the CPU.

Other filters are more CPU-intensive -- using the Chorus filter on 64 samples, for instance, takes about 8% of the CPU. You can use the AIL_digital_CPU_percent function to check the CPU demands imposed by the filter(s) your application uses.

Next Topic (How can I play two HSAMPLEs from the same memory address?)

Previous Topic (How do I set a DSP filter on a sample?)

Group: FAQs and How Tos
Related Functions: AIL_digital_CPU_percent


How can I play two HSAMPLEs from the same memory address?

Miles Sound System SDK 7.2a

Q:

How can I play two HSAMPLEs from the same memory address?

A:

You don't have to do anything special to play from the same memory location in Miles - you just tell us to play two HSAMPLEs from the same memory pointer!

So, just allocate two HSAMPLEs with AIL_allocate_sample_handle and then point both at the same address with the AIL_set_sample_file, AIL_set_named_sample_file, or AIL_set_sample_info functions.

Remember that Miles reads out of your memory! So, if you want to play two HSAMPLEs (or three, or ten, etc) from the same memory location, just pass the allocate two HSAMPLES and point each one to the same address with the AIL_set_sample_file / AIL_set_sample_info family.

Next Topic (When can I free the memory I gave to MSS?)

Previous Topic (How much CPU do the various filters use?)

Group: FAQs and How Tos
Related Functions: AIL_allocate_sample_handle, AIL_set_named_sample_file, AIL_set_sample_file, AIL_set_sample_info


When can I free the memory I gave to MSS?

Miles Sound System SDK 7.2a

Q:

When can I free the memory I gave to MSS?

A:

Since Miles plays out of your memory buffers, you can't free the memory until you know that Miles is done with it.

For example, if you've pointed Miles at some audio data with AIL_set_sample_file, AIL_set_sample_info, or AIL_set_named_sample_file, you can't free the memory until AIL_sample_status returns SMP_DONE. You can call AIL_end_sample to instantly force the status to SMP_DONE.

Occasionally, a crash will occur when a Miles user is freeing sample memory. This may seem to suggest that Miles is still using the data even after the status has changed to SMP_DONE.

Over the last ten years, there have a fair number of folks convinced that this is what was happening (with varying degrees of certainty). In all cases, something else was causing the crash - memory corruption (which using causes a crash in free), another sample was also playing from the same address, etc. Just remember - if SMP_DONE has been set, you can free the memory as long as another sample isn't using it. Guaranteed!

Next Topic (How do I start an audio file somewhere in the middle?)

Previous Topic (How can I play two HSAMPLEs from the same memory address?)

Group: FAQs and How Tos
Related Functions: AIL_end_sample, AIL_mem_free_lock, AIL_sample_status, AIL_set_named_sample_file, AIL_set_sample_file, AIL_set_sample_info
Related Basic Types: MILES_DIGITAL_STATUS
Related FAQs: My application is crashing - what should I try?


How do I start an audio file somewhere in the middle?

Miles Sound System SDK 7.2a

Q:

How do I start an audio file somewhere in the middle?

A:

In all of the Miles APIs (digital, MIDI, and stream-based), when you call the "start" function (like AIL_start_sample, for example), the sound will restart at the beginning of the audio file.

So, to play an audio file from the middle, open the sound file, skip to an offset, and then start the playback with one of the "resume" functions (like AIL_resume_sample).

Next Topic (How do I smoothly ramp up or ramp down the volume of a sample over time?)

Previous Topic (When can I free the memory I gave to MSS?)

Group: FAQs and How Tos
Related Functions: AIL_pause_stream, AIL_resume_sample, AIL_resume_sequence, AIL_start_sample, AIL_start_sequence, AIL_start_stream


How do I smoothly ramp up or ramp down the volume of a sample over time?

Miles Sound System SDK 7.2a

Q:

How do I smoothly ramp up or ramp down the volume of a sample over time?

A:

There is a special digital filter for this very purpose. To use it, you attach the filter to the sample, and then just set the time and ramp levels that you want to use. To find the filter and attach it to the HSAMPLE, you would use code like this:

HPROVIDER volume_ramp;
if ( AIL_find_filter( "Volume Ramp Filter", &volume_ramp ) )
{
  AIL_set_sample_processor( S, SP_FILTER_0, volume_ramp );
}

Once you've done this, the sample can be volume-ramped whenever you like. You set the level once with the ramp time at zero to set the starting ramp level, and then again with a non-zero ramp time to set the final level and begin the ramping. Remember to always set the ramp time first, and then the ramp level. So, to smoothly ramp the volume up from 0.0 to 1.0, use something like this:

// First, set the ramp time to zero, to init the ramp level
F32 ramp_time = 0.0f;
AIL_sample_stage_property( S, SP_FILTER_0, "Ramp Time", 0, &ramp_time, 0 );
//
// we want start at level zero
F32 ramp_level = 0.0f;
AIL_sample_stage_property( S, SP_FILTER_0, "Ramp To", 0, &ramp_level, 0 );
//
//
//ok now, set the ramp time to 1000 ms (fade in over 1 second)
ramp_time = 1000.0f;
AIL_sample_stage_property( S, SP_FILTER_0, "Ramp Time", 0, &ramp_time, 0 );
//
// ramp up to 1.0 (full volume)
F32 ramp_level = 1.0f;
AIL_sample_stage_property( S, SP_FILTER_0, "Ramp To", 0, &ramp_level, 0 );

Similarly, to fade out over one second, do something like this:

// First, set the ramp time to zero, to init the ramp level
F32 ramp_time = 0.0f;
AIL_sample_stage_property( S, SP_FILTER_0, "Ramp Time", 0, &ramp_time, 0 );
//
// we want start at full volume
F32 ramp_level = 1.0f;
AIL_sample_stage_property( S, SP_FILTER_0, "Ramp To", 0, &ramp_level, 0 );
//
//
//ok now, set the ramp time to 1000 ms (fade out over 1 second)
ramp_time = 1000.0f;
AIL_sample_stage_property( S, SP_FILTER_0, "Ramp Time", 0, &ramp_time, 0 );
//
// ramp down to 0.0 (silence)
F32 ramp_level = 0.0f;
AIL_sample_stage_property( S, SP_FILTER_0, "Ramp To", 0, &ramp_level, 0 );

Note that the filter remembers the last ramp level, so you only have to set the starting ramp level if you don't already know what it is. So, if you ramp from 0.0 to 1.0, and then later want to ramp back down to 0.0, you don't need to set the initial ramp level to 1.0.

Next Topic (How do I play a 3D digital sound?)

Previous Topic (How do I start an audio file somewhere in the middle?)

Group: FAQs and How Tos
Related Sections: Volume Ramp Filter


How do I play a 3D digital sound?

Miles Sound System SDK 7.2a

Q:

How do I play a 3D digital sound?

A:

Just like you'd play a 2D one, except that to give the sound a position in 3D space, you'll need to pass its location to AIL_set_sample_3D_position. Unless your sound positions are relative to a listener at the origin, you'll also want to pass the listener's location to AIL_set_listener_3D_position.

Note that 3D audio data should be mono (not stereo) under most circumstances. See the "How can I assign 3D positions to stereo samples?" FAQ for more details.

Most likely, your application will also need to use the AIL_set_sample_3D_distances function to set the 3D volume-falloff characteristics. See the "My 3D sound isn't falling off like I expected..." FAQ for more details on 3D distances.

Next Topic (My 3D sound isn't falling off like I expected - what's going on?)

Previous Topic (How do I smoothly ramp up or ramp down the volume of a sample over time?)

Group: FAQs and How Tos
Related Functions: AIL_set_listener_3D_position, AIL_set_sample_3D_distances, AIL_set_sample_3D_position
Related FAQs: How can I assign 3D positions to stereo samples?, My 3D sound isn't falling off like I expected - what's going on?


My 3D sound isn't falling off like I expected - what's going on?

Miles Sound System SDK 7.2a

Q:

My 3D sound isn't falling off like I expected - what's going on?

A:

This is a common source of confusion. Basically, the most important thing to remember is that the maximum distance has nothing to do with the volume falloff curve! Only the minimum distance matters for the falloff curve.

The volume of a sample falls off by half every time the minimum distance is doubled. So, if you set your minimum distance to 3, then this falloff curve is in effect:

Distance: less than or equal to 3 meters. Volume: 100%.
Distance: 6 meters. Volume 50%.
Distance: 12 meters. Volume 25%.
Distance: 24 meters. Volume 12.5%.
Distance: 48 meters. Volume 6.25%.
etc...

So, you can see that the maximum distance doesn't affect the volume falloff curve at all! The maximum distance just sets a hard clip point - the volume is forced to be zero at maximum.

Also note that some DirectSound drivers don't implement the maximum distance correctly with the DSBCAPS_MUTE3DATMAXDISTANCE flag in effect (which Miles uses). At the maximum distance on these drivers, the volume doesn't drop to zero, instead, it just stops falling off.

Next Topic (How can I assign 3D positions to stereo samples?)

Previous Topic (How do I play a 3D digital sound?)

Group: FAQs and How Tos
Related Functions: AIL_sample_3D_distances, AIL_set_sample_3D_distances
Related FAQs: How do I play a 3D digital sound?


How can I assign 3D positions to stereo samples?

Miles Sound System SDK 7.2a

Q:

How can I assign 3D positions to stereo samples?

A:

You can't, at least not meaningfully, and not on a cross-platform basis. Hardware providers like DirectSound3D/EAX won't accept stereo data at all, and the software mixer will route stereo channels to pairs of speakers which are adjacent in an arbitrarily-ordered list defined by Microsoft as part of the WDM driver model, which isn't a particularly-meaningful thing to do under most conditions.

You can call AIL_process_digital_audio to convert stereo data to mono where necessary. In general, you should just not use stereo sound data, though. It's almost certainly not what you want.

Next Topic (My 3D audio is a lot louder than my 2D audio - what can I do?)

Previous Topic (My 3D sound isn't falling off like I expected - what's going on?)

Group: FAQs and How Tos
Related Functions: AIL_process_digital_audio
Related FAQs: How do I play a 3D digital sound?


My 3D audio is a lot louder than my 2D audio - what can I do?

Miles Sound System SDK 7.2a
Q: | My 3D audio is a lot louder than my 2D audio - what can I do?
A: | Some 3D-capable hardware doesn't have very good balance between their 3D samples and 2D samples. There isn't a good way to automatically deal with this, because it's a sound card-specific problem. One solution is to give the user a slider in your normal volume-setting options screen and let them balance the two types of audio themselves. The other solution, which we recommend for most applications that encounter trouble with this issue, is to avoid using DirectSound3D and EAX altogether in favor of a software-based option when you call AIL_open_digital_driver.

Next Topic (How do I set an environmental reverb room style?)

Previous Topic (How can I assign 3D positions to stereo samples?)

Group: FAQs and How Tos
Related Functions: AIL_open_digital_driver


How do I set an environmental reverb room style?

Miles Sound System SDK 7.2a

Q:

How do I set an environmental reverb room style?

A:

Simply call AIL_set_room_type on the HDIGDRIVER. This will establish default reverb characteristics for the specified room type, which you can modify if you like with AIL_set_digital_master_reverb and AIL_set_digital_master_reverb_levels.

You will also need to use AIL_set_sample_reverb_levels to turn the wet effects level up for the 3D samples that should have reverb. The per-sample wet level defaults to 0.0, so if you're not hearing your selected room effects, this is probably why!

Next Topic (How does Miles do sound prioritization?)

Previous Topic (My 3D audio is a lot louder than my 2D audio - what can I do?)

Group: FAQs and How Tos
Related Functions: AIL_set_digital_master_reverb, AIL_set_digital_master_reverb_levels, AIL_set_sample_reverb_levels


How does Miles do sound prioritization?

Miles Sound System SDK 7.2a

Q:

How does Miles do sound prioritization?

A:

It doesn't. Philosophically, RAD has never been a big fan of handling sound prioritization at the library level. The way Miles works, the application can just allocate sample handles until it hits the system-imposed limit. The application is then responsible for reusing those handles in whatever way it sees fit. You can use whatever criteria you wish to bump playing sounds (age, importance, distance, volume, the existence of duplicates, etc.), or decide not to bump any at all if the new sound isn't that important.

A lot of that flexibility goes away, or becomes awkward to access, if you make Miles responsible for killing existing sounds in favor of new ones.

Next Topic (On the Sony PS2, how can I use the IOP or SPU memory to hold my audio?)

Previous Topic (How do I set an environmental reverb room style?)

Group: FAQs and How Tos


On the Sony PS2, how can I use the IOP or SPU memory to hold my audio?

Miles Sound System SDK 7.2a

Q:

On the Sony PS2, how can I use the IOP or SPU memory to hold my audio?

A:

You can load data into IOP or SPU memory using the RAD_IOPQueueAsyncReadAtTop function with the proper destination pointer type.

Then, to use this data later, you can either copy it into EE memory using the same RAD_IOPQueueAsyncReadAtTop function, or, more convienently, you can simply stream the digital audio directly out of these other memory banks using the AIL_open_stream function.

Next Topic (I can't seem to change the volume of my XMIDI sequences, what's going on?)

Previous Topic (How does Miles do sound prioritization?)

Group: FAQs and How Tos
Related Functions: AIL_open_stream, RAD_IOPQueueAsyncReadAtTop


I can't seem to change the volume of my XMIDI sequences, what's going on?

Miles Sound System SDK 7.2a
Q: | I can't seem to change the volume of my XMIDI sequences, what's going on?
A: | This is probably because your XMIDI sequence doesn't have any default volume events. Miles can't change the volume of a sequence until the baseline level is specified with a MIDI volume event. Have your musician insert volume events at the beginning of the sequence and you should then be able to control the volume with AIL_set_sequence_volume.

Next Topic (What's the deal with callbacks - are they threads, interrupts, system timers, or what?)

Previous Topic (On the Sony PS2, how can I use the IOP or SPU memory to hold my audio?)

Group: FAQs and How Tos
Related Functions: AIL_set_sequence_volume


What's the deal with callbacks - are they threads, interrupts, system timers, or what?

Miles Sound System SDK 7.2a
Q: | What's the deal with callbacks - are they threads, interrupts, system timers, or what?
A: | It all depends on the platform: On Win32, Win64 and PS3, callbacks are usually made from a background thread. On MacOS, callbacks are usually made from an interrupt-based system callback on MacOS 9 and a background thread on MacOS X. On PS2, callbacks are usually made from a hardware interrupt. On Wii, callbacks are usually made from a hardware alarm interrupt. On DOS, callbacks are usually made from a hardware interrupt.

Next Topic (How much latency does Miles have?)

Previous Topic (I can't seem to change the volume of my XMIDI sequences, what's going on?)

Group: FAQs and How Tos
Related Sections: Callbacks on Playstation 3, Callbacks under DOS, Callbacks under MacOS, Callbacks under Nintendo Wii, Callbacks under PlayStation 2, Callbacks under Win32, Callbacks under Win64
Related Functions: AIL_register_EOB_callback, AIL_register_EOS_callback, AIL_register_SOB_callback, AIL_register_beat_callback, AIL_register_event_callback, AIL_register_falloff_function_callback, AIL_register_prefix_callback, AIL_register_sequence_callback, AIL_register_stream_callback, AIL_register_timbre_callback, AIL_register_timer, AIL_register_trigger_callback


How much latency does Miles have?

Miles Sound System SDK 7.2a

Q:

How much latency does Miles have?

A:

The AIL_digital_latency function can roughly report the current latency. This section will discuss where this latency comes from on each of the Miles platforms.

On Win32/Win64 with DirectSound, the default latency is 64 milliseconds (not counting the OS, sound driver and sound hardware latency which is out of our control). You can reduce or increase the latency by changing the DIG_DS_MIX_FRAGMENT_CNT preference. If you shorten the latency, you increase the chance of skipping. If you lengthen the latency, you can ride out longer thread starvations.

On Win32 with waveOut, the latency depends on the sound card and sound card drivers. Miles calculates the minimum latency that won't cause skipping at runtime. On most cards, this will be 150 ms to 200 ms, but on some sound cards (especially older ISA cards), this latency can rise to as high as 300 ms! These excessive latency times with waveOut environment are due to fundamental design shortcomings in the Microsoft architecture, and cannot be reliably overcome by any external techniques.

However, under waveOut, the MSS architecture does permit a sound effect to be started with essentially zero latency, as long as no other sound effects are currently being played! So, if you have a situation where latency is critical, then you can improve waveOut's performance dramatically by letting all other sounds complete before starting the latency-critical sound effect.

On PS3, the default latency is 40 milliseconds (not counting the OS latency which is out of our control). You can reduce or increase the latency by changing the DIG_DS_MIX_FRAGMENT_CNT preference. If you shorten the latency, you increase the chance of skipping. If you lengthen the latency, you can ride out longer thread starvations.

On Wii, the default latency is 32 milliseconds (not counting the OS latency which is out of our control). You can reduce or increase the latency by changing the DIG_DS_MIX_FRAGMENT_CNT preference. If you shorten the latency, you increase the chance of skipping. If you lengthen the latency, you can ride out longer thread starvations.

On MacOS, the default latency is 64 milliseconds (not counting the OS, sound driver and sound hardware latency which is out of our control). You can reduce or increase the latency by changing the DIG_SM_MIX_FRAGMENT_CNT preference. If you shorten the latency, you increase the chance of skipping. If you lengthen the latency, you can ride out longer thread starvations.

On DOS, the default latency is 100 milliseconds. You can reduce or increase the latency by changing the DIG_LATENCY preference. If you shorten the latency, you increase the chance of skipping. Under DOS, there is little reason to change the default latency.

Next Topic (My sound is skipping on Windows or MacOS X - what can I do?)

Previous Topic (What's the deal with callbacks - are they threads, interrupts, system timers, or what?)

Group: FAQs and How Tos
Related Functions: AIL_digital_latency
Related Basic Types: MILES_PREFERENCES


My sound is skipping on Windows or MacOS X - what can I do?

Miles Sound System SDK 7.2a

Q:

My sound is skipping on Windows or MacOS X - what can I do?

A:

Under Win32, Win64 and MacOS X, mixing happens on a background thread (on the other Miles platforms, mixing occurs on an interrupt). Unlike interrupts, threads are subject to starvation - that is, depending on CPU load, one thread can be neglected for a period of time.

When that happens to the Miles mixing thread, then the digital audio can "skip" momentarily. Fortunately, on NT-based Windows platforms and fast Macs running Mac OS X, this rarely happens - you really have to try to cause a skip. Unfortunately, on the Windows 9x based platforms and on slower Macs, it is fairly easy to cause the Miles thread to starve. The easiest way to trigger starvation is to do a lot of sustained disk IO on an IDE-based device.

So, regardless of the cause of the problem, we just want the user to have a good experience. A simple way to fix the problem is to just mix ahead farther - if we mix ahead 200 milliseconds, then we can tolerate a thread dropout of up to 200 ms with no trouble! The only problem is that now our latency is 200 ms - fine for some games, but terrible for others!

Fortunately, there is a good compromise. By using the AIL_get_timer_highest_delay function, you can track the length of the thread starvations as they occur.

So, let's say you have a game that skips when you read in the level data from the disk. The best way to fix the problem is something like this:

1) Call AIL_get_timer_highest_delay before you start the I/O (this clears the previous high value).

2) Do all your IO.

3) Call AIL_get_timer_highest_delay and record it.

Run your game on a couple machines and keep track of the high value. It's usually going to be something around 150 milliseconds, but get a good reading with your game's pattern of IO.

Now we just bump up the latency during the I/O and then bump it back down after - you get the best of both worlds - good latency in the general case, and enough mix ahead to handle the I/O dropouts. Once you know roughly what latency you have to cover, simply do something like this:

1) On Win32/Win64, call AIL_set_preference on DIG_DS_MIX_FRAGMENT_CNT to your highest timer delay divided by 8 (each fragment in Miles is 8 ms on Windows).

On MacOS, call AIL_set_preference on DIG_SM_MIX_FRAGMENT_CNT to your highest timer delay divided by 8 (each fragment in Miles is 8 ms on the Mac).

2) Call AIL_serve to make sure that the mix-ahead buffer is filled.

3) Do all your IO.

4) On Win32/Win64, call AIL_set_preference on DIG_DS_MIX_FRAGMENT_CNT to set it back to its default value of 8.

On MacOS, call AIL_set_preference on DIG_SM_MIX_FRAGMENT_CNT to set it back to its default value of 8.

Next Topic (My application is crashing - what should I try?)

Previous Topic (How much latency does Miles have?)

Group: FAQs and How Tos
Related Sections: Sharing the CPU under MacOS, Sharing the CPU under Win32, Sharing the CPU under Win64
Related Functions: AIL_get_timer_highest_delay, AIL_serve, AIL_set_preference
Related Basic Types: MILES_PREFERENCES


My application is crashing - what should I try?

Miles Sound System SDK 7.2a

Q:

My application is crashing - what should I try?

A:

Here's my quick list of things to ask yourself when you get a crash. Most of them seem really obvious, but one of these questions solves pretty much every technical support query we get!

Go through the questions one by one and don't assume the answer to any of them - actually explore each question. Without fail, the most complicated crashes are usually reduced to one simple assumption that was never completely confirmed.

1) What call is crashing? Does it crash every time, or just once in a while?

2) If you cut that call into one of the Miles sample applications, does it still crash?

3) Is the problem data-dependent? Do other sound files work?

4) Don't overlook the obvious - what are the contents of the parameters being passed to the crashing function? Are they valid? Double-check them at run-time in the debugger.

5) Are you using the latest version of Miles? See the "What is the latest version of MSS?" FAQ for details.

6) Make sure that the header file, the DLLs and shared libraries, and all of the add-on files (the ASIs, FLTs, etc) are all the same version! Scan your drive for the Miles library files - make sure there are none on your drive except the very latest version.

7) Miles is used in a lot of games (about 700 per year). If you are getting a crash, try to imagine what is different about your application - are you doing anything you'd guess is unusual?

8) Try never freeing your sound memory buffers. You'll leak memory, but if you don't crash, then you are probably freeing a piece of memory before Miles is done with it. See the "When can I free the memory I gave to MSS?" FAQ for details.

9) Does it happen on a specific machine? On a specific OS? Does it only happen with a particular sound card? Do you have the latest sound card drivers for your sound card?

10) Does it only happen when a particular channel specification (MSS_MC_SPEC value) is passed to AIL_open_digital_driver?

11) Create and examine a Miles call log (see the call logging sections in the Overview sections of this document). Does anything appear unusual?

12) Build the Miles DLL in debug mode - can you tell what's happening from the crash location in the source code? See the "How can I rebuild the Miles source code?" FAQ for details.

13) Try simplifying the problem. Turn off everything unnecessary (DSP filters, 3D spatialization, reverb, etc.) - does it affect the crash?

14) Are you using callbacks? Try turning them off completely - does it still crash?

15) Finally, if you've been able to reproduce a crash in Miles, send us the example (keep it short and simple - the console applications in the \Examples directory are a good place to start) and we'll get it fixed for you. RAD can usually fix reproducable problems within days!

Next Topic (Where is the Miles source code? How can I rebuild it (in debug mode)?)

Previous Topic (My sound is skipping on Windows or MacOS X - what can I do?)

Group: FAQs and How Tos
Related Sections: Call Logging under DOS, Call Logging under MacOS, Call Logging under Nintendo, Call Logging under PlayStation 2, Call Logging under PlayStation 3, Call Logging under Win32, Call Logging under Win64, Call Logging under Xbox, Call Logging under Xbox 360
Related Functions: AIL_open_digital_driver
Related Basic Types: MSS_MC_SPEC
Related FAQs: What is the latest version of MSS?, When can I free the memory I gave to MSS?, Where is the Miles source code? How can I rebuild it (in debug mode)?


Where is the Miles source code? How can I rebuild it (in debug mode)?

Miles Sound System SDK 7.2a

Q:

Where is the Miles source code? How can I rebuild it (in debug mode)?

A:

Almost all of the source code is included with Miles. How you rebuild it depends on the platform:

To build Miles on Win32/Win64:

1) Edit setdirs.bat in the "\src" directory and modify it to point to your installation of Microsoft Visual C and MASM (use short pathnames).

2) Run the Debug.BAT or the Release.BAT files in "\src\sdk", "\src\tools", and the "\src\examples" directories.

To build Miles on MacOS:

1) Load the miles library project, miles filters project, and the miles asi project files in the "/src/sdk" directory into CodeWarrior and do a rebuild all.

To build Miles on DOS:

1) Edit setdirs.bat in the "\src" directory and modify it to point to your installation of Watcom C and MASM (use short pathnames).

2) Run the Debug.BAT or the Release.BAT files in "\src\sdk", "\src\tools", and the "\src\examples" directories.

Next Topic (How can I tell what version of Miles that I have?)

Previous Topic (My application is crashing - what should I try?)

Group: FAQs and How Tos
Related Sections: Call Logging under DOS, Call Logging under MacOS, Call Logging under Nintendo, Call Logging under PlayStation 2, Call Logging under PlayStation 3, Call Logging under Win32, Call Logging under Win64, Call Logging under Xbox, Call Logging under Xbox 360
Related FAQs: My application is crashing - what should I try?


How can I tell what version of Miles that I have?

Miles Sound System SDK 7.2a

Q:

How can I tell what version of Miles that I have?

A:

It depends on when and what version you'd like to check.

At runtime, you can call the AIL_MSS_version function to get the library version.

You can get the header file version by looking at the top of the MSS.H file. You can check the version of any of the Windows DLLs (including ASIs and FLTs) by right-clicking on the file in Explorer, choosing "Properties" and then clicking on the Version tab.

You can check the version of the Mac shared libraries (including ASIs and FLTs) by using the Finder menu option "Get Info...".

Next Topic (What is the latest version of MSS?)

Previous Topic (Where is the Miles source code? How can I rebuild it (in debug mode)?)

Group: FAQs and How Tos
Related Functions: AIL_MSS_version


What is the latest version of MSS?

Miles Sound System SDK 7.2a
Q: | What is the latest version of MSS?
A: | You can always see what the latest version of Miles is (and see what has changed) by checking the Miles website.

Next Topic (How do I use a Unicode path on Windows?)

Previous Topic (How can I tell what version of Miles that I have?)

Group: FAQs and How Tos
Related FAQs: My application is crashing - what should I try?


How do I use a Unicode path on Windows?

Miles Sound System SDK 7.2a

Q:

How do I use a Unicode path on Windows?

A:

The Miles DLL is compiled in ascii character mode so that it can work on Windows 9x without any extra DLLs.

That means if your Miles application is installed in a Unicode path, then the redistributable add-ons (for MP3 playback, DSP filters, etc) won't be found.

So, to fix this, you follow these steps:

1) Have your installer create a normal ascii path under your main application directory for the Miles files (usually you'd do this anyway, creating a "redist" directory).

2) Before calling AIL_startup, use the Win32/Win64 Unicode function SetCurrentDirectoryW to make sure that the current directory is set to your main application directory.

3) Call AIL_set_redist_directory with the relative pathname to your Miles redistribution directory, only put a "*" character in front of the path. So, for example, instead of "redist", use "*redist".

4) Finally, call AIL_startup as you would normally.

All of the files should then load correctly (whether on a Unicode path or not).

Next Topic (How do I access files from a big packed file?)

Previous Topic (What is the latest version of MSS?)

Group: FAQs and How Tos
Related Sections: Distributing Miles with Win32 Applications, Distributing Miles with Win64 Applications
Related Functions: AIL_set_redist_directory, AIL_startup


How do I access files from a big packed file?

Miles Sound System SDK 7.2a

Q:

How do I access files from a big packed file?

A:

One solution is to use the AIL_set_file_callbacks function to point to your own routines for doing I/O. A better one for most applications is to take advantage of AIL_open_stream's ability to accept a system file handle (on Win32/Win64, see FileHndl.c for an example).

You can also use AIL_set_file_async_callbacks to point to your own routines for doing asynchronous I/O on certain platforms. Asynchronous streaming is used by default on MacOS 9, Wii and PS2 - the other platforms use synchronous IO from a background thread.

Most applications should allow Miles to manage its own file access. There are very few reasons to provide your own file-access callbacks to Miles... and with Miles's extensive use of multithreading, there are a lot of things that can go wrong if you do.

Next Topic (I'm setting a preference and it isn't having any effect - what's going on?)

Previous Topic (How do I use a Unicode path on Windows?)

Group: FAQs and How Tos
Related Functions: AIL_open_stream, AIL_set_file_async_callbacks, AIL_set_file_callbacks


I'm setting a preference and it isn't having any effect - what's going on?

Miles Sound System SDK 7.2a

Q:

I'm setting a preference and it isn't having any effect - what's going on?

A:

Usually, when this happens, you are setting the preference after it has a chance to take effect. For example, if you set DIG_MIXER_CHANNELS to 128, but do it after you've called AIL_open_digital_driver, then it won't have a chance to apply.

Also remember that preferences are reset by a call to AIL_startup, so don't set your preferences too early or forget to reset them if you ever restart Miles.

Next Topic (I want a small installation - do I need all of the files in the \redist directories?)

Previous Topic (How do I access files from a big packed file?)

Group: FAQs and How Tos
Related Functions: AIL_open_digital_driver, AIL_startup
Related Basic Types: MILES_PREFERENCES


I want a small installation - do I need all of the files in the \redist directories?

Miles Sound System SDK 7.2a

Q:

I want a small installation - do I need all of the files in the \redist directories?

A:

No, you only have to use the files that you intend to use. You have to have the main Miles library file (MSS32.DLL under Win32, for example), but the other files are optional.

If you aren't using any of the DSP pipeline filters, then you don't need the MSSDSP.FLT file, for example.

You may not need to include the output filters discussed in the Digital Audio Services Section - if you aren't planning to support a particular matrix or voice-level 3D technology, just don't ship the corresponding FLT file.

The ASI files provide compression and decompression support in Miles. The MSSMP3.ASI file, for example, is the MP3 decoder. The MSSVoice.ASI, file contains the Voxware voice chat codecs. If you don't use one or more of these audio codecs, then you don't need to ship them!

Next Topic (I'm using Windows 9x or NT - do I have to call the AIL_mem_alloc_lock function?)

Previous Topic (I'm setting a preference and it isn't having any effect - what's going on?)

Group: FAQs and How Tos
Related FAQs: What are these ASI and FLT files? What is RIB?


I'm using Windows 9x or NT - do I have to call the AIL_mem_alloc_lock function?

Miles Sound System SDK 7.2a
Q: | I'm using Windows 9x or NT - do I have to call the AIL_mem_alloc_lock function?
A: | Only if you want to make porting easier to MacOS 9 or DOS. Under Win32, you can just pass in any memory buffer to Miles - malloc-ed, GlobalAlloc-ed, resource locked, etc.

Next Topic (How careful do I have to be when shutting down?)

Previous Topic (I want a small installation - do I need all of the files in the \redist directories?)

Group: FAQs and How Tos


How careful do I have to be when shutting down?

Miles Sound System SDK 7.2a

Q:

How careful do I have to be when shutting down?

A:

Not very - if you simply call AIL_shutdown, Miles will shut everything that you have opened (the digital system, the MIDI system, any open streams, the 3D providers, etc).

Miles doesn't, however, automatically free any memory that you have allocated with AIL_mem_alloc_lock or AIL_file_read, so make sure to free all your Miles allocated memory before the call to AIL_shutdown.

Next Topic (This function returns a bunch of return data, but I only want one value - is there a simpler way to use it?)

Previous Topic (I'm using Windows 9x or NT - do I have to call the AIL_mem_alloc_lock function?)

Group: FAQs and How Tos
Related Functions: AIL_file_read, AIL_mem_alloc_lock, AIL_shutdown


This function returns a bunch of return data, but I only want one value - is there a simpler way to use it?

Miles Sound System SDK 7.2a

Q:

This function returns a bunch of return data, but I only want one value - is there a simpler way to use it?

A:

Yes, throughout Miles, it is legal to pass in zero for almost every return pointer. If the pointer you pass Miles is zero, then it just doesn't set that return value.

For example, in AIL_sample_ms_position both the total length of the sample and the current position are returned. If you just need the total length, you can pass in zero for the current position parameter and Miles just won't return it.

Next Topic (The Internet voice chat example has a lot of latency or it doesn't work on my LAN - what's going on?)

Previous Topic (How careful do I have to be when shutting down?)

Group: FAQs and How Tos
Related Functions: AIL_sample_ms_position


The Internet voice chat example has a lot of latency or it doesn't work on my LAN - what's going on?

Miles Sound System SDK 7.2a

Q:

The Internet voice chat example has a lot of latency or it doesn't work on my LAN - what's going on?

A:

There are two equally important subsystems when doing Internet voice chat. The first is the sound system - this subsystem captures the data, compresses, decompresses it, and then outputs it. This is the side of the problem that Miles solves: it has the input, voice chat codecs, and killer output side.

The other half of the problem is the network layer. This is usually a UDP-based network transport layer that your game also uses for communication. The key thing to remember is that Miles doesn't have any network layer! A good network layer is at least as big of a problem as sound itself, and it's way out of MSS's domain. There are, in fact, complete licensable products that just supply the network communication for a game.

So, the voice chat examples that we supply are just that - examples. You can use the examples to see how to call the input, codec, and output systems, but they won't help you on the network side. We just implemented the least complicated protocol possible to keep the rest of the example easy (it's already fairly complex).

So, the examples use the high-level TCP/IP protocol for communication - this works fine on a LAN with access to a DNS server, but it definitely will have trouble over the Internet unless you replace the network pieces.

We have extensive documentation on integrating the voice chat codecs with a generic network layer - see the "Implementing Voice Chat" Section for more details.

Next Topic (What are these ASI and FLT files? What is RIB?)

Previous Topic (This function returns a bunch of return data, but I only want one value - is there a simpler way to use it?)

Group: FAQs and How Tos


What are these ASI and FLT files? What is RIB?

Miles Sound System SDK 7.2a

Q:

What are these ASI and FLT files? What is RIB?

A:

RIB stands for RAD Interface Broker - it is RAD's mechanism for expanding and enhancing the system through the use of dynamically-loadable modules. These modules, called RIBs, are designed in conformance with the new RAD Interface Broker (RIB) standard. ASI and FLT files are RIB-based loadable modules.

ASI files are sound codecs - MP3 decoding support is provided by the MSSMP3.ASI file, for example.

FLT files are digital sound filters. All of the default sample-pipeline filters are in the MSSDSP.FLT file. In MSS 7, FLT files can also provide per-voice DirectSound3D/EAX support and matrix (Dolby/SRS) support. This functionality was handled by M3D files in previous releases.

This is all you really need to know about RIB to use Miles, but if you are interesting in the technical underpinnings of RIB, read on...

The RIB standard allows either MSS or the application itself to scan a directory for installable modules, load them, query their properties, and take advantage of the features they offer at runtime, all in a manner that's completely transparent to your application. RIBs deliver many of the same benefits of "component-oriented" design that are commonly associated with more complex and proprietary industry standards such as Microsoft's COM model, but on an open, cross-platform basis, and with several key features designed to avoid many of the headaches that eventually come to plague users of other runtime object models.

As with most component-based models in use today, RIB components represent individual functions and data elements as collective members of named interfaces. Unlike more familiar object models such as those associated with MS COM and even C++ itself, however, an application's view of a particular RIB interface and its elements is determined completely by the application itself, and not the RIB component provider or any of its header files. The MSS RIB manager implements true dynamic binding at no additional cost in runtime performance. By way of illustration, three different ways to instantiate the same object might look like:

C++ With Static Binding

MyStream = new MP3Stream;

MS COM With Runtime Binding

MP3StreamFactory->QueryInterface(IID_Stream,
                                 (void **) &MyStream);

RAD Interface Broker With Runtime Binding

STR_OPEN STR_open;
...
HPROPERTY OUTPUT_SAMPLE_RATE
...
RIB_INTERFACE_ENTRY MyStreamInterface[] =
{
   FN(STR_property),
   FN(STR_open),
   FN(STR_close),
   FN(STR_process),
   PR("Output sample rate",    OUTPUT_SAMPLE_RATE),
   PR("Output sample width",   OUTPUT_BITS),
   PR("Output channels",       OUTPUT_CHANNELS)
}
HSTREAM STR = RIB_find_file_provider("Audio stream",
                                     "Input file types",
                                     "*.MP3");
RIB_request(STR,
           "Audio stream",
            MyStreamInterface);
MyStreamHandle = STR_open();

It's apparent at a glance that the RIB-based example is, if nothing else, more complex. What benefits are being gained with all that extra code? The answer lies in a fundamental aspect of the RIB system's design: RIB interfaces specify content, not structure. RIB components never reveal the exact layout of their interfaces to the application. A RIB interface name is only used to refer to a collection of available, related functions and data properties. Unlike a C++ class, a RIB interface does not expose implementation details which have to be artificially segregated from the outside world with "private" or "public" labels. And unlike an MS COM interface, a RIB interface does not introduce dangerous dependencies on the underlying language's virtual-function table model, including the number of functions an interface provider offers and the order in which its function prototypes appear in a class declaration. As suggested by the example above, each RIB application is able to specify its own view of the functions and data exposed by its component providers. The binding of the provider's resources with the application's declarations takes place dynamically, via the RIB_request function. There are several advantages to this approach:

- No more obsolete header files. A RIB component's header file contains only the typedef'ed prototypes for the functions exported by the component at its time of release. The application declares variables of these types to receive function pointers when RIB_request is called to resolve its requested functions by name. Data properties are resolved in a similar manner, through the use of tokens which are passed down from the provider to the caller via RIB_request.

- No more broken interfaces. A RIB interface does not contain or imply any implementation details such as the order in which its functions appear in an internal virtual-method table. Consequently, new functions and data members may be exposed in subsequent releases, without "breaking" any existing application compiled with an older version of the component's header file. Similarly, different providers of the same interface (e.g., an MPEG audio decoder and an IMA ADPCM audio decoder) can export provider-specific properties and functions, which the application can either enumerate or ask for explicitly at runtime. Applications are also free to request functions and properties which may not be supported by all providers of a given interface, taking advantage of optional features when available and degrading gracefully otherwise.

- Full runtime browsability. All communication between RIB components and their calling applications takes place via functions and properties whose names are presented as plain-text ASCII strings. This applies as well to the names of the components' interfaces themselves. The RIB manager API allows the names, members, and types of all interface elements to be enumerated in a standardized fashion, making it possible for general-purpose component browsers to be developed for all providers of a given interface.

What does this mean to you, as the creator of your own MSS applications? The good news is that we've made it easy for you to take advantage of the new RIB providers without getting involved in the details of the RIB component model. MSS's API has been expanded to make access to both the 3D audio and MPEG compression feature sets as painless as possible. Most application authors will never come into direct contact with the RIB manager API that's built into MSS. For the curious, however, the complete RIB API documentation is available in RIB.H. Specific RIB interface specs used by Miles are found in MSS.H.

In short, RAD believes that the component-oriented RAD Interface Broker model is the best way to make sure that MSS grows with your needs. We feel it's one of the more exciting features of the new system, even though its implications may be lost amidst the excitement of the new features and tools!

Previous Topic (The Internet voice chat example has a lot of latency or it doesn't work on my LAN - what's going on?)

Group: FAQs and How Tos
Related FAQs: I want a small installation - do I need all of the files in the \redist directories?


Basic Types

Discussion

Miles strives to be as cross-platform as possible. To this end, Miles uses a set of basic types that are configured for each platform to ensure consistency in the API.

These basic types include simple integer types, float types, and more. In general, it is best if an application uses Miles's types internally in places where it interfaces to Miles, as this ensures that porting the application to other Miles platforms will be quick and easy.

Basic Types
S8 | describes a signed 8-bit integer.
U8 | describes an unsigned 8-bit integer.
S16 | describes a signed 16-bit integer.
U16 | describes an unsigned 16-bit integer.
S64 | describes a signed 64-bit integer.
U64 | describes an unsigned 64-bit integer.
S32 | describes a signed 32-bit integer.
U32 | describes an unsigned 32-bit integer.
SINTa | describes a signed integer that is the same size as a pointer on the current platform. Right now, only Win64 currently uses 64-bit pointers, so on everything else this is a 32-bit integer.
UINTa | describes an unsigned integer that is the same size as a pointer on the current platform. Right now, only Win64 currently uses 64-bit pointers, so on everything else this is a 32-bit integer.
F32 | describes a standard 32-bit floating-point number.
F64 | describes a standard 64-bit double-precision floating-point number.
void | describes a standard C/C++ void return type.
void * | describes a standard C/C++ untyped memory pointer.
void const * | describes a constant (unchangeable) C/C++ untyped memory pointer.
char | describes a single character type.
char * | describes a normal zero-terminated C-style string.
char const * | describes a constant (unchangeable) zero-terminated C-style string.
HDIGDRIVER | is a handle to an digital audio device.
HMDIDRIVER | is a handle to an midi output device.
HDLSDEVICE | is a handle to an DLS device.
HDIGINPUT | is a handle to an digital audio input device.
HPROVIDER | is a handle to an available RIB provider.
HDRIVERSTATE | is a handle to an open digital audio filter.
HTIMER | is a handle to a Miles timer callback.
HSAMPLE | is a handle to a digital sound sample.
HAUDIO | is a handle to a quick API handle (it can contain digital or MIDI data).
HSTREAM | is a handle to a digital audio stream.
HREDBOOK | is a handle to a CD audio (redbook) device.
HSEQUENCE | is a handle to an XMIDI sequence.
HWAVESYNTH | is a handle to an open wave synthesizer.
HDLSFILEID | is a handle to an loaded DLS instrument set.
HPROENUM | specifies a type used to enumerate through a list of RIB providers.
HINTENUM | specifies a type used to enumerate through a list of properties.
AIL_DRIVER | specifies a low-level digital or XMIDI DOS driver.
REALFAR | specifies a lower 1 MB real mode address.
LPDIRECTSOUND | describes a pointer to a DirectSound object.
LPDIRECTSOUNDBUFFER | describes a pointer to a DirectSound buffer object.
HWND | specifies a Windows window handle.
LPHWAVEOUT | specifies a pointer to a Windows waveOut device.
LPHMIDIOUT | specifies a pointer to a Windows midiOut device.
FSSpec | is a MacOS file spec structure used on Classic and Carbon.
VOID_PTR | describes a standard C/C++ untyped memory pointer.
CHAR_PTR | describes a normal zero-terminated C-style string.


S8

The basic type S8 describes a signed 8-bit integer.

Group: Basic Types


U8

The basic type U8 describes an unsigned 8-bit integer.

Group: Basic Types
Related Structures: VDI_HDR


S16

The basic type S16 describes a signed 16-bit integer.

Group: Basic Types
Related Structures: IO_PARMS, VDI_CALL


U16

The basic type U16 describes an unsigned 16-bit integer.

Group: Basic Types
Related Structures: VDI_HDR


S64

The basic type S64 describes a signed 64-bit integer.

Group: Basic Types


U64

The basic type U64 describes an unsigned 64-bit integer.

Group: Basic Types


S32

The basic type S32 describes a signed 32-bit integer.

Group: Basic Types
Related Functions: AILBEATCB, AILCODECSETPROP, AILEVENTCB, AILLENGTHYCB, AILPREFIXCB, AILTIMBRECB, AILTRACECB, AILTRIGGERCB, AIL_DLS_get_info, AIL_MDI_driver_type, AIL_MIDI_handle_reacquire, AIL_MIDI_handle_release, AIL_MIDI_to_XMI, AIL_WAV_file_fss_write, AIL_WAV_file_write, AIL_WAV_info, AIL_XMIDI_master_volume, AIL_active_sample_count, AIL_active_sequence_count, AIL_auto_service_stream, AIL_background, AIL_calculate_3D_channel_levels, AIL_call_driver, AIL_channel_notes, AIL_compress_ADPCM, AIL_compress_ASI, AIL_compress_DLS, AIL_controller_value, AIL_create_wave_synthesizer, AIL_decompress_ADPCM, AIL_decompress_ASI, AIL_delay, AIL_digital_CPU_percent, AIL_digital_configuration, AIL_digital_handle_reacquire, AIL_digital_handle_release, AIL_digital_latency, AIL_enumerate_MP3_frames, AIL_enumerate_filter_properties, AIL_enumerate_filter_sample_properties, AIL_enumerate_filters, AIL_enumerate_output_filter_driver_properties, AIL_enumerate_output_filter_sample_properties, AIL_enumerate_sample_stage_properties, AIL_extract_DLS, AIL_file_async_status_callback, AIL_file_error, AIL_file_fss_attrib_write, AIL_file_fss_size, AIL_file_fss_write, AIL_file_seek_callback, AIL_file_size, AIL_file_type, AIL_file_type_named, AIL_file_write, AIL_filter_DLS_with_XMI, AIL_filter_property, AIL_find_DLS, AIL_find_filter, AIL_init_sample, AIL_init_sequence, AIL_input_callback, AIL_inspect_MP3, AIL_install_DIG_INI, AIL_install_MDI_INI, AIL_install_timbre, AIL_list_DLS, AIL_list_MIDI, AIL_load_sample_buffer, AIL_lock_channel, AIL_map_sequence_channel, AIL_merge_DLS_with_XMI, AIL_midiOutOpen, AIL_minimum_sample_buffer_size, AIL_open_digital_driver, AIL_open_stream, AIL_output_filter_driver_property, AIL_pause_stream, AIL_platform_property, AIL_process_digital_audio, AIL_protect_timbre, AIL_quick_fss_load_and_play, AIL_quick_load_and_play, AIL_quick_ms_length, AIL_quick_ms_position, AIL_quick_play, AIL_quick_set_ms_position, AIL_quick_set_speed, AIL_quick_startup, AIL_quick_status, AIL_quick_type, AIL_read_INI, AIL_redbook_set_volume_level, AIL_register_trace_callback, AIL_release_channel, AIL_room_type, AIL_sample_3D_distances, AIL_sample_3D_position, AIL_sample_buffer_available, AIL_sample_buffer_count, AIL_sample_buffer_info, AIL_sample_channel_count, AIL_sample_channel_levels, AIL_sample_loop_block, AIL_sample_loop_count, AIL_sample_ms_position, AIL_sample_output_levels, AIL_sample_playback_rate, AIL_sample_stage_property, AIL_send_channel_voice_message, AIL_sequence_loop_count, AIL_sequence_ms_position, AIL_sequence_position, AIL_sequence_tempo, AIL_sequence_volume, AIL_service_stream, AIL_set_DirectSound_HWND, AIL_set_XMIDI_master_volume, AIL_set_input_state, AIL_set_named_sample_file, AIL_set_room_type, AIL_set_sample_3D_distances, AIL_set_sample_buffer_count, AIL_set_sample_channel_levels, AIL_set_sample_file, AIL_set_sample_info, AIL_set_sample_loop_block, AIL_set_sample_loop_count, AIL_set_sample_ms_position, AIL_set_sample_playback_rate, AIL_set_sequence_loop_count, AIL_set_sequence_ms_position, AIL_set_sequence_tempo, AIL_set_sequence_volume, AIL_set_speaker_configuration, AIL_set_speaker_reverb_levels, AIL_set_stream_loop_block, AIL_set_stream_loop_count, AIL_set_stream_ms_position, AIL_set_stream_position, AIL_size_processed_digital_audio, AIL_speaker_configuration, AIL_speaker_reverb_levels, AIL_startup, AIL_stream_info, AIL_stream_loop_count, AIL_stream_ms_position, AIL_stream_position, AIL_stream_status, AIL_timbre_status, AIL_true_sequence_channel, AIL_unprotect_timbre, AIL_vmm_lock, AIL_vmm_lock_range, AIL_vmm_unlock, AIL_vmm_unlock_range, RAD_IOPCancelAllAsyncs, RAD_IOPCancelAsyncOpen, RAD_IOPCancelAsyncRead, RAD_IOPCancelFileAsyncs, RAD_IOPCancelGroupOfAsyncs, RAD_IOPCloseFile, RAD_IOPFindNonPlayingVoiceMask, RAD_IOPGetIOStatus, RAD_IOPHardwareVolumes, RAD_IOPPauseSound, RAD_IOPPauseTimer, RAD_IOPQueueAsyncOpenFile, RAD_IOPQueueAsyncReadAtBottom, RAD_IOPQueueAsyncReadAtTop, RAD_IOPQueueAsyncSPUGlobalState, RAD_IOPQueueAsyncSPUVoiceState, RAD_IOPRegisterSoundCallback, RAD_IOPRegisterTimerCallback, RAD_IOPSetSPUVoiceADSR, RAD_IOPSetSPUVoiceLoopAddress, RAD_IOPSetSPUVoiceMixOnOff, RAD_IOPSetSPUVoiceOnOff, RAD_IOPSetSPUVoicePitch, RAD_IOPSetSPUVoiceStartAddress, RAD_IOPSetSPUVoiceVolume, RAD_IOPShutDown, RAD_IOPStartSound, RAD_IOPStartUp, RAD_IOPUnregisterSoundCallback, RAD_IOPUnregisterTimerCallback
Related Structures: AILDLSINFO, AILSOUNDINFO, AIL_INPUT_INFO, EAX_AUTOGAIN, EAX_AUTOWAH, EAX_CHORUS, EAX_DISTORTION, EAX_ECHO, EAX_EQUALIZER, EAX_FLANGER, EAX_FSHIFTER, EAX_PSHIFTER, EAX_REVERB, EAX_RMODULATOR, EAX_SAMPLE_SLOT_VOLUME, EAX_VMORPHER, IO_PARMS, MP3_INFO, RAD_IOP_ASYNC_OPEN_DATA, RAD_IOP_ASYNC_READ_DATA, RAD_IOP_SOUND_DATA, RAD_IOP_SPU_GLOBAL_STATE, RAD_IOP_SPU_VOICE_STATE


U32

The basic type U32 describes an unsigned 32-bit integer.

Group: Basic Types
Related Functions: AILLENGTHYCB, AILMALLOCCB, AIL_DLS_close, AIL_DLS_load_file, AIL_DLS_load_memory, AIL_DLS_open, AIL_MIDI_to_XMI, AIL_MSS_version, AIL_WAV_file_fss_write, AIL_WAV_file_write, AIL_branch_index, AIL_compress_ADPCM, AIL_compress_ASI, AIL_compress_DLS, AIL_decompress_ADPCM, AIL_decompress_ASI, AIL_disable_interrupts, AIL_extract_DLS, AIL_file_async_read_callback, AIL_file_async_status_callback, AIL_file_fss_attrib_write, AIL_file_fss_write, AIL_file_open_callback, AIL_file_read_callback, AIL_file_seek_callback, AIL_file_type, AIL_file_type_named, AIL_file_write, AIL_filter_DLS_with_XMI, AIL_find_DLS, AIL_get_preference, AIL_get_real_vect, AIL_get_timer_highest_delay, AIL_init_sample, AIL_install_DIG_driver_image, AIL_install_MDI_driver_image, AIL_install_driver, AIL_interrupt_divisor, AIL_list_DLS, AIL_list_MIDI, AIL_load_sample_buffer, AIL_mem_alloc_lock, AIL_merge_DLS_with_XMI, AIL_ms_count, AIL_open_XMIDI_driver, AIL_open_digital_driver, AIL_process_digital_audio, AIL_quick_fss_load_and_play, AIL_quick_load_and_play, AIL_quick_load_mem, AIL_quick_load_named_mem, AIL_quick_play, AIL_quick_startup, AIL_redbook_id, AIL_redbook_open, AIL_redbook_pause, AIL_redbook_play, AIL_redbook_position, AIL_redbook_resume, AIL_redbook_status, AIL_redbook_stop, AIL_redbook_track, AIL_redbook_track_info, AIL_redbook_tracks, AIL_restore_interrupts, AIL_restore_stack, AIL_sample_buffer_info, AIL_sample_channel_count, AIL_sample_granularity, AIL_sample_position, AIL_sample_status, AIL_sample_user_data, AIL_sequence_status, AIL_sequence_user_data, AIL_set_USE16_ISR, AIL_set_named_sample_file, AIL_set_preference, AIL_set_real_vect, AIL_set_sample_address, AIL_set_sample_adpcm_block_size, AIL_set_sample_position, AIL_set_sample_user_data, AIL_set_sequence_user_data, AIL_set_stream_user_data, AIL_set_timer_divisor, AIL_set_timer_frequency, AIL_set_timer_period, AIL_size_processed_digital_audio, AIL_stream_user_data, AIL_switch_stack, AIL_us_count, AIL_vmm_lock, RADTimerRead, RAD_IOPCancelGroupOfAsyncs, RAD_IOPFindNonPlayingVoiceMask, RAD_IOPGetFileHandleToIOPMemory, RAD_IOPGetFileHandleToLSN, RAD_IOPGetFileHandleToSPUMemory, RAD_IOPHardwareVolumes, RAD_IOPMemoryAmount, RAD_IOPSetSPUVoiceADSR, RAD_IOPSetSPUVoiceLoopAddress, RAD_IOPSetSPUVoiceMixOnOff, RAD_IOPSetSPUVoiceOnOff, RAD_IOPSetSPUVoicePitch, RAD_IOPSetSPUVoiceStartAddress, RAD_IOPSetSPUVoiceVolume, RAD_IOPStartTimer, RAD_IOPStartUp
Related Structures: AILSOUNDINFO, AIL_INPUT_INFO, EAX_AUTOGAIN, EAX_CHORUS, EAX_FLANGER, EAX_FSHIFTER, EAX_REVERB, EAX_RMODULATOR, EAX_SAMPLE_SLOT_VOLUMES, EAX_VMORPHER, RAD_IOP_ASYNC_OPEN_DATA, RAD_IOP_ASYNC_READ_DATA, RAD_IOP_SOUND_DATA, RAD_IOP_SPU_GLOBAL_STATE, RAD_IOP_SPU_VOICE_STATE, VDI_HDR


SINTa

The basic type SINTa describes a signed integer that is the same size as a pointer on the current platform. Right now, only Win64 currently uses 64-bit pointers, so on everything else this is a 32-bit integer.

Group: Basic Types
Related Functions: AIL_get_preference, AIL_sample_user_data, AIL_sequence_user_data, AIL_set_preference, AIL_set_sample_user_data, AIL_set_sequence_user_data, AIL_set_stream_user_data, AIL_stream_user_data


UINTa

The basic type UINTa describes an unsigned integer that is the same size as a pointer on the current platform. Right now, only Win64 currently uses 64-bit pointers, so on everything else this is a 32-bit integer.

Group: Basic Types
Related Functions: AILLENGTHYCB, AILTIMERCB, AIL_file_async_read_callback, AIL_file_close_callback, AIL_file_open_callback, AIL_file_read_callback, AIL_file_seek_callback, AIL_input_callback, AIL_set_timer_user
Related Structures: AIL_INPUT_INFO, RIB_INTERFACE_ENTRY


F32

The basic type F32 describes a standard 32-bit floating-point number.

Group: Basic Types
Related Functions: AILFALLOFFCB, AIL_3D_distance_factor, AIL_3D_doppler_factor, AIL_3D_rolloff_factor, AIL_calculate_3D_channel_levels, AIL_digital_master_reverb, AIL_digital_master_reverb_levels, AIL_digital_master_volume_level, AIL_listener_3D_orientation, AIL_listener_3D_position, AIL_listener_3D_velocity, AIL_quick_set_low_pass_cut_off, AIL_quick_set_reverb_levels, AIL_quick_set_volume, AIL_redbook_set_volume_level, AIL_redbook_volume_level, AIL_sample_3D_cone, AIL_sample_3D_distances, AIL_sample_3D_orientation, AIL_sample_3D_position, AIL_sample_3D_velocity, AIL_sample_51_volume_levels, AIL_sample_51_volume_pan, AIL_sample_channel_levels, AIL_sample_exclusion, AIL_sample_low_pass_cut_off, AIL_sample_obstruction, AIL_sample_occlusion, AIL_sample_output_levels, AIL_sample_reverb_levels, AIL_sample_volume_levels, AIL_sample_volume_pan, AIL_set_3D_distance_factor, AIL_set_3D_doppler_factor, AIL_set_3D_rolloff_factor, AIL_set_digital_master_reverb, AIL_set_digital_master_reverb_levels, AIL_set_digital_master_volume_level, AIL_set_listener_3D_orientation, AIL_set_listener_3D_position, AIL_set_listener_3D_velocity, AIL_set_listener_3D_velocity_vector, AIL_set_sample_3D_cone, AIL_set_sample_3D_distances, AIL_set_sample_3D_orientation, AIL_set_sample_3D_position, AIL_set_sample_3D_velocity, AIL_set_sample_3D_velocity_vector, AIL_set_sample_51_volume_levels, AIL_set_sample_51_volume_pan, AIL_set_sample_exclusion, AIL_set_sample_low_pass_cut_off, AIL_set_sample_obstruction, AIL_set_sample_occlusion, AIL_set_sample_reverb_levels, AIL_set_sample_volume_levels, AIL_set_sample_volume_pan, AIL_set_speaker_configuration, AIL_speaker_configuration, AIL_update_listener_3D_position, AIL_update_sample_3D_position
Related Structures: EAX_AUTOWAH, EAX_CHORUS, EAX_DISTORTION, EAX_ECHO, EAX_EQUALIZER, EAX_FLANGER, EAX_FSHIFTER, EAX_REVERB, EAX_RMODULATOR, EAX_SAMPLE_SLOT_VOLUME, EAX_VMORPHER


F64

The basic type F64 describes a standard 64-bit double-precision floating-point number.

Group: Basic Types


void

The basic type void describes a standard C/C++ void return type.

Group: Basic Types
Related Functions: AILBEATCB, AILFREECB, AILMALLOCCB, AILSAMPLECB, AILSEQUENCECB, AILSTREAMCB, AILTIMERCB, AILTRACECB, AILTRIGGERCB, AIL_DLS_close, AIL_DLS_compact, AIL_DLS_get_info, AIL_DLS_unload, AIL_MSS_version, AIL_auto_service_stream, AIL_branch_index, AIL_close_XMIDI_driver, AIL_close_digital_driver, AIL_close_filter, AIL_close_input, AIL_close_stream, AIL_delay, AIL_destroy_wave_synthesizer, AIL_digital_configuration, AIL_digital_master_reverb, AIL_digital_master_reverb_levels, AIL_end_sample, AIL_end_sequence, AIL_file_async_read_callback, AIL_file_close_callback, AIL_file_fss_read, AIL_file_read, AIL_file_read_callback, AIL_filter_property, AIL_get_DirectSound_info, AIL_input_callback, AIL_inspect_MP3, AIL_listener_3D_orientation, AIL_listener_3D_position, AIL_listener_3D_velocity, AIL_load_sample_buffer, AIL_lock, AIL_map_sequence_channel, AIL_mem_alloc_lock, AIL_mem_free_lock, AIL_mem_use_free, AIL_mem_use_malloc, AIL_output_filter_driver_property, AIL_pause_stream, AIL_platform_property, AIL_process_digital_audio, AIL_protect_timbre, AIL_quick_halt, AIL_quick_handles, AIL_quick_set_low_pass_cut_off, AIL_quick_set_ms_position, AIL_quick_set_reverb_levels, AIL_quick_set_speed, AIL_quick_set_volume, AIL_quick_shutdown, AIL_quick_unload, AIL_redbook_close, AIL_redbook_eject, AIL_redbook_retract, AIL_redbook_track_info, AIL_register_ICA_array, AIL_release_all_timers, AIL_release_channel, AIL_release_sample_handle, AIL_release_sequence_handle, AIL_release_timer_handle, AIL_restore_stack, AIL_resume_sample, AIL_resume_sequence, AIL_sample_3D_cone, AIL_sample_3D_distances, AIL_sample_3D_orientation, AIL_sample_3D_velocity, AIL_sample_51_volume_levels, AIL_sample_51_volume_pan, AIL_sample_channel_levels, AIL_sample_ms_position, AIL_sample_output_levels, AIL_sample_reverb_levels, AIL_sample_stage_property, AIL_sample_volume_levels, AIL_sample_volume_pan, AIL_scratchpad_policy, AIL_send_channel_voice_message, AIL_send_sysex_message, AIL_sequence_ms_position, AIL_sequence_position, AIL_serve, AIL_set_3D_distance_factor, AIL_set_3D_doppler_factor, AIL_set_3D_rolloff_factor, AIL_set_GTL_filename_prefix, AIL_set_XMIDI_master_volume, AIL_set_digital_master_reverb, AIL_set_digital_master_reverb_levels, AIL_set_digital_master_volume_level, AIL_set_file_async_callbacks, AIL_set_file_callbacks, AIL_set_listener_3D_orientation, AIL_set_listener_3D_position, AIL_set_listener_3D_velocity, AIL_set_listener_3D_velocity_vector, AIL_set_real_vect, AIL_set_room_type, AIL_set_sample_3D_cone, AIL_set_sample_3D_distances, AIL_set_sample_3D_orientation, AIL_set_sample_3D_position, AIL_set_sample_3D_velocity, AIL_set_sample_3D_velocity_vector, AIL_set_sample_51_volume_levels, AIL_set_sample_51_volume_pan, AIL_set_sample_address, AIL_set_sample_adpcm_block_size, AIL_set_sample_channel_levels, AIL_set_sample_exclusion, AIL_set_sample_loop_block, AIL_set_sample_loop_count, AIL_set_sample_low_pass_cut_off, AIL_set_sample_ms_position, AIL_set_sample_obstruction, AIL_set_sample_occlusion, AIL_set_sample_playback_rate, AIL_set_sample_position, AIL_set_sample_reverb_levels, AIL_set_sample_user_data, AIL_set_sample_volume_levels, AIL_set_sample_volume_pan, AIL_set_sequence_loop_count, AIL_set_sequence_ms_position, AIL_set_sequence_tempo, AIL_set_sequence_user_data, AIL_set_sequence_volume, AIL_set_speaker_configuration, AIL_set_speaker_reverb_levels, AIL_set_stream_loop_block, AIL_set_stream_loop_count, AIL_set_stream_ms_position, AIL_set_stream_position, AIL_set_stream_user_data, AIL_set_timer_divisor, AIL_set_timer_frequency, AIL_set_timer_period, AIL_shutdown, AIL_start_all_timers, AIL_start_sample, AIL_start_sequence, AIL_start_stream, AIL_start_timer, AIL_stop_all_timers, AIL_stop_sample, AIL_stop_sequence, AIL_stop_timer, AIL_stream_info, AIL_stream_ms_position, AIL_switch_stack, AIL_uninstall_driver, AIL_unlock, AIL_unprotect_timbre, AIL_update_listener_3D_position, AIL_update_sample_3D_position, RAD_IOP_OPENCALLBACK, RAD_IOP_READCALLBACK, RAD_IOP_SOUNDCALLBACK, RAD_IOP_SPU_GLOBAL_STATE_CALLBACK, RAD_IOP_SPU_VOICE_STATE_CALLBACK, RAD_IOP_TIMERCALLBACK, Register_RIB


void *

The basic type void * describes a standard C/C++ untyped memory pointer.

Group: Basic Types
Related Functions: AILMALLOCCB, AIL_MIDI_to_XMI, AIL_compress_ADPCM, AIL_compress_ASI, AIL_compress_DLS, AIL_decompress_ADPCM, AIL_decompress_ASI, AIL_extract_DLS, AIL_file_async_read_callback, AIL_file_async_status_callback, AIL_file_fss_read, AIL_file_read, AIL_filter_DLS_with_XMI, AIL_find_DLS, AIL_mem_alloc_lock, AIL_mem_use_free, AIL_mem_use_malloc, AIL_merge_DLS_with_XMI, AIL_restore_stack, Register_RIB
Related Structures: AILSOUNDINFO, VDI_HDR


void const *

The basic type void const * describes a constant (unchangeable) C/C++ untyped memory pointer.

Group: Basic Types
Related Functions: AILCODECSETPROP, AILFREECB, AIL_DLS_load_memory, AIL_MIDI_to_XMI, AIL_WAV_file_fss_write, AIL_WAV_file_write, AIL_WAV_info, AIL_compress_DLS, AIL_create_wave_synthesizer, AIL_decompress_ASI, AIL_extract_DLS, AIL_file_fss_attrib_write, AIL_file_fss_write, AIL_file_type, AIL_file_type_named, AIL_file_write, AIL_filter_DLS_with_XMI, AIL_filter_property, AIL_find_DLS, AIL_init_sequence, AIL_input_callback, AIL_install_DIG_driver_image, AIL_install_MDI_driver_image, AIL_list_DLS, AIL_list_MIDI, AIL_load_sample_buffer, AIL_mem_free_lock, AIL_merge_DLS_with_XMI, AIL_output_filter_driver_property, AIL_platform_property, AIL_quick_load_mem, AIL_quick_load_named_mem, AIL_sample_stage_property, AIL_send_sysex_message, AIL_set_named_sample_file, AIL_set_sample_address, AIL_set_sample_file, AIL_vmm_lock, AIL_vmm_lock_range, AIL_vmm_unlock, AIL_vmm_unlock_range


char

The basic type char describes a single character type.

Group: Basic Types
Related Functions: AIL_MSS_version, AIL_digital_configuration, AIL_last_error, AIL_redbook_open_drive, AIL_set_redist_directory
Related Structures: VDI_HDR


char *

The basic type char * describes a normal zero-terminated C-style string.

Group: Basic Types
Related Functions: AILTRACECB, AIL_enumerate_filters, AIL_find_filter, AIL_last_error, AIL_list_DLS, AIL_list_MIDI, AIL_set_redist_directory
Related Structures: VDI_HDR


char const *

The basic type char const * describes a constant (unchangeable) zero-terminated C-style string.

Group: Basic Types
Related Functions: AILCODECSETPROP, AIL_DLS_load_file, AIL_DLS_open, AIL_WAV_file_write, AIL_compress_ASI, AIL_compress_DLS, AIL_decompress_ASI, AIL_file_open_callback, AIL_file_read, AIL_file_size, AIL_file_type_named, AIL_file_write, AIL_filter_property, AIL_install_DIG_driver_file, AIL_install_MDI_driver_file, AIL_list_DLS, AIL_open_stream, AIL_output_filter_driver_property, AIL_quick_load, AIL_quick_load_and_play, AIL_quick_load_named_mem, AIL_read_INI, AIL_redbook_open_volume, AIL_sample_stage_property, AIL_set_GTL_filename_prefix, AIL_set_named_sample_file, AIL_set_redist_directory
Related Structures: AIL_INI, RIB_INTERFACE_ENTRY


HDIGDRIVER

The basic type HDIGDRIVER is a handle to an digital audio device.

Discussion

HDIGDRIVER handles are returned from the AIL_open_digital_driver function.

Group: Basic Types
Related Functions: AIL_3D_distance_factor, AIL_3D_doppler_factor, AIL_3D_rolloff_factor, AIL_DLS_open, AIL_active_sample_count, AIL_allocate_sample_handle, AIL_calculate_3D_channel_levels, AIL_close_digital_driver, AIL_create_wave_synthesizer, AIL_digital_CPU_percent, AIL_digital_configuration, AIL_digital_driver_processor, AIL_digital_handle_reacquire, AIL_digital_handle_release, AIL_digital_latency, AIL_digital_master_reverb, AIL_digital_master_reverb_levels, AIL_digital_master_volume_level, AIL_digital_output_filter, AIL_install_DIG_INI, AIL_install_DIG_driver_file, AIL_install_DIG_driver_image, AIL_listener_3D_orientation, AIL_listener_3D_position, AIL_listener_3D_velocity, AIL_minimum_sample_buffer_size, AIL_open_digital_driver, AIL_open_filter, AIL_open_stream, AIL_output_filter_driver_property, AIL_quick_handles, AIL_room_type, AIL_set_3D_distance_factor, AIL_set_3D_doppler_factor, AIL_set_3D_rolloff_factor, AIL_set_DirectSound_HWND, AIL_set_digital_driver_processor, AIL_set_digital_master_reverb, AIL_set_digital_master_reverb_levels, AIL_set_digital_master_volume_level, AIL_set_listener_3D_orientation, AIL_set_listener_3D_position, AIL_set_listener_3D_velocity, AIL_set_listener_3D_velocity_vector, AIL_set_room_type, AIL_set_speaker_configuration, AIL_set_speaker_reverb_levels, AIL_speaker_configuration, AIL_speaker_reverb_levels, AIL_update_listener_3D_position


HMDIDRIVER

The basic type HMDIDRIVER is a handle to an midi output device.

Discussion

HMDIDRIVER handles are returned from the AIL_open_XMIDI_driver function.

Group: Basic Types
Related Functions: AILBEATCB, AILEVENTCB, AILTIMBRECB, AIL_DLS_open, AIL_MDI_driver_type, AIL_MIDI_handle_reacquire, AIL_MIDI_handle_release, AIL_XMIDI_master_volume, AIL_active_sequence_count, AIL_allocate_sequence_handle, AIL_close_XMIDI_driver, AIL_create_wave_synthesizer, AIL_install_MDI_INI, AIL_install_MDI_driver_file, AIL_install_MDI_driver_image, AIL_install_timbre, AIL_lock_channel, AIL_midiOutOpen, AIL_open_XMIDI_driver, AIL_protect_timbre, AIL_quick_handles, AIL_register_beat_callback, AIL_register_event_callback, AIL_register_timbre_callback, AIL_release_channel, AIL_send_channel_voice_message, AIL_send_sysex_message, AIL_set_XMIDI_master_volume, AIL_timbre_status, AIL_unprotect_timbre


HDLSDEVICE

The basic type HDLSDEVICE is a handle to an DLS device.

Discussion

HDLSDEVICE handles are returned from the AIL_DLS_open function.

Group: Basic Types
Related Functions: AIL_DLS_close, AIL_DLS_compact, AIL_DLS_get_info, AIL_DLS_load_file, AIL_DLS_load_memory, AIL_DLS_open, AIL_DLS_sample_handle, AIL_DLS_unload, AIL_quick_handles


HDIGINPUT

The basic type HDIGINPUT is a handle to an digital audio input device.

Discussion

HDIGINPUT handles are returned from the AIL_open_input function.

Group: Basic Types
Related Functions: AIL_close_input, AIL_get_input_info, AIL_open_input, AIL_set_input_state


HPROVIDER

The basic type HPROVIDER is a handle to an available RIB provider.

Discussion

HPROVIDER handles are returned from the AIL_enumerate_filters, AIL_find_filter, AIL_set_sample_processor, AIL_set_digital_driver_processor, AIL_sample_processor, AIL_digital_driver_processor, and AIL_digital_output_filter functions.

Group: Basic Types
Related Functions: AIL_digital_driver_processor, AIL_digital_output_filter, AIL_enumerate_filter_properties, AIL_enumerate_filter_sample_properties, AIL_enumerate_filters, AIL_enumerate_output_filter_driver_properties, AIL_enumerate_output_filter_sample_properties, AIL_filter_property, AIL_find_filter, AIL_open_filter, AIL_sample_processor, AIL_set_digital_driver_processor, AIL_set_sample_processor


HDRIVERSTATE

The basic type HDRIVERSTATE is a handle to an open digital audio filter.

Discussion

HDRIVERSTATE handles are returned from the AIL_open_filter function.

This handle type isn't strictly necessary, because Miles will automatically open a digital filter upon first use if you don't do it.

Group: Basic Types
Related Functions: AIL_close_filter, AIL_open_filter


HTIMER

The basic type HTIMER is a handle to a Miles timer callback.

Discussion

HTIMER handles are returned from the AIL_register_timer function.

Group: Basic Types
Related Functions: AIL_register_timer, AIL_release_timer_handle, AIL_set_timer_divisor, AIL_set_timer_frequency, AIL_set_timer_period, AIL_set_timer_user, AIL_start_timer, AIL_stop_timer


HSAMPLE

The basic type HSAMPLE is a handle to a digital sound sample.

Discussion

HSAMPLE handles are returned from the AIL_allocate_sample_handle function.

Group: Basic Types
Related Functions: AILFALLOFFCB, AILSAMPLECB, AIL_DLS_sample_handle, AIL_allocate_sample_handle, AIL_end_sample, AIL_enumerate_sample_stage_properties, AIL_get_DirectSound_info, AIL_init_sample, AIL_load_sample_buffer, AIL_register_EOB_callback, AIL_register_EOS_callback, AIL_register_SOB_callback, AIL_register_falloff_function_callback, AIL_release_sample_handle, AIL_resume_sample, AIL_sample_3D_cone, AIL_sample_3D_distances, AIL_sample_3D_orientation, AIL_sample_3D_position, AIL_sample_3D_velocity, AIL_sample_51_volume_levels, AIL_sample_51_volume_pan, AIL_sample_buffer_available, AIL_sample_buffer_count, AIL_sample_buffer_info, AIL_sample_channel_count, AIL_sample_channel_levels, AIL_sample_exclusion, AIL_sample_granularity, AIL_sample_loop_block, AIL_sample_loop_count, AIL_sample_low_pass_cut_off, AIL_sample_ms_position, AIL_sample_obstruction, AIL_sample_occlusion, AIL_sample_output_levels, AIL_sample_playback_rate, AIL_sample_position, AIL_sample_processor, AIL_sample_reverb_levels, AIL_sample_stage_property, AIL_sample_status, AIL_sample_user_data, AIL_sample_volume_levels, AIL_sample_volume_pan, AIL_set_named_sample_file, AIL_set_sample_3D_cone, AIL_set_sample_3D_distances, AIL_set_sample_3D_orientation, AIL_set_sample_3D_position, AIL_set_sample_3D_velocity, AIL_set_sample_3D_velocity_vector, AIL_set_sample_51_volume_levels, AIL_set_sample_51_volume_pan, AIL_set_sample_address, AIL_set_sample_adpcm_block_size, AIL_set_sample_buffer_count, AIL_set_sample_channel_levels, AIL_set_sample_exclusion, AIL_set_sample_file, AIL_set_sample_info, AIL_set_sample_loop_block, AIL_set_sample_loop_count, AIL_set_sample_low_pass_cut_off, AIL_set_sample_ms_position, AIL_set_sample_obstruction, AIL_set_sample_occlusion, AIL_set_sample_playback_rate, AIL_set_sample_position, AIL_set_sample_processor, AIL_set_sample_reverb_levels, AIL_set_sample_user_data, AIL_set_sample_volume_levels, AIL_set_sample_volume_pan, AIL_start_sample, AIL_stop_sample, AIL_stream_sample_handle, AIL_update_sample_3D_position


HAUDIO

The basic type HAUDIO is a handle to a quick API handle (it can contain digital or MIDI data).

Discussion

HAUDIO handles are returned from the AIL_quick_load function.

Group: Basic Types
Related Functions: AIL_quick_copy, AIL_quick_fss_load, AIL_quick_fss_load_and_play, AIL_quick_halt, AIL_quick_load, AIL_quick_load_and_play, AIL_quick_load_mem, AIL_quick_load_named_mem, AIL_quick_ms_length, AIL_quick_ms_position, AIL_quick_play, AIL_quick_set_low_pass_cut_off, AIL_quick_set_ms_position, AIL_quick_set_reverb_levels, AIL_quick_set_speed, AIL_quick_set_volume, AIL_quick_status, AIL_quick_type, AIL_quick_unload


HSTREAM

The basic type HSTREAM is a handle to a digital audio stream.

Discussion

HSTREAM handles are returned from the AIL_open_stream function.

Group: Basic Types
Related Functions: AILSTREAMCB, AIL_auto_service_stream, AIL_close_stream, AIL_open_stream, AIL_pause_stream, AIL_register_stream_callback, AIL_sample_buffer_count, AIL_service_stream, AIL_set_sample_buffer_count, AIL_set_stream_loop_block, AIL_set_stream_loop_count, AIL_set_stream_ms_position, AIL_set_stream_position, AIL_set_stream_user_data, AIL_start_stream, AIL_stream_info, AIL_stream_loop_count, AIL_stream_ms_position, AIL_stream_position, AIL_stream_sample_handle, AIL_stream_status, AIL_stream_user_data


HREDBOOK

The basic type HREDBOOK is a handle to a CD audio (redbook) device.

Discussion

HREDBOOK handles are returned from the AIL_redbook_open function.

Group: Basic Types
Related Functions: AIL_redbook_close, AIL_redbook_eject, AIL_redbook_id, AIL_redbook_open, AIL_redbook_open_drive, AIL_redbook_open_volume, AIL_redbook_pause, AIL_redbook_play, AIL_redbook_position, AIL_redbook_resume, AIL_redbook_retract, AIL_redbook_set_volume_level, AIL_redbook_status, AIL_redbook_stop, AIL_redbook_track, AIL_redbook_track_info, AIL_redbook_tracks, AIL_redbook_volume_level


HSEQUENCE

The basic type HSEQUENCE is a handle to an XMIDI sequence.

Discussion

HSEQUENCE handles are returned from the AIL_allocate_sequence_handle function.

Group: Basic Types
Related Functions: AILBEATCB, AILEVENTCB, AILPREFIXCB, AILSEQUENCECB, AILTRIGGERCB, AIL_allocate_sequence_handle, AIL_branch_index, AIL_channel_notes, AIL_controller_value, AIL_end_sequence, AIL_init_sequence, AIL_map_sequence_channel, AIL_register_ICA_array, AIL_register_prefix_callback, AIL_register_sequence_callback, AIL_register_trigger_callback, AIL_release_sequence_handle, AIL_resume_sequence, AIL_send_channel_voice_message, AIL_sequence_loop_count, AIL_sequence_ms_position, AIL_sequence_position, AIL_sequence_status, AIL_sequence_tempo, AIL_sequence_user_data, AIL_sequence_volume, AIL_set_sequence_loop_count, AIL_set_sequence_ms_position, AIL_set_sequence_tempo, AIL_set_sequence_user_data, AIL_set_sequence_volume, AIL_start_sequence, AIL_stop_sequence, AIL_true_sequence_channel


HWAVESYNTH

The basic type HWAVESYNTH is a handle to an open wave synthesizer.

Discussion

HWAVESYNTH handles are returned from the AIL_create_wave_synthesizer function.

Group: Basic Types
Related Functions: AIL_create_wave_synthesizer, AIL_destroy_wave_synthesizer


HDLSFILEID

The basic type HDLSFILEID is a handle to an loaded DLS instrument set.

Discussion

HDLSFILEID handles are returned from the AIL_DLS_load_file and AIL_DLS_load_memory functions.

Group: Basic Types
Related Functions: AIL_DLS_load_file, AIL_DLS_load_memory, AIL_DLS_unload


HPROENUM

The basic type HPROENUM specifies a type used to enumerate through a list of RIB providers.

Discussion

The Miles provider enumeration functions all work similarly - you set a local variable of type HPROENUM to HPROENUM_FIRST and then call the enumeration function until it returns failure.

Group: Basic Types
Related Functions: AIL_enumerate_filters


HINTENUM

The basic type HINTENUM specifies a type used to enumerate through a list of properties.

Discussion

The Miles property enumeration functions all work similarly - you set a local variable of type HINTENUM to HINTENUM_FIRST and then call the enumeration function until it returns failure.

Group: Basic Types
Related Functions: AIL_enumerate_filter_properties, AIL_enumerate_filter_sample_properties, AIL_enumerate_output_filter_driver_properties, AIL_enumerate_output_filter_sample_properties, AIL_enumerate_sample_stage_properties


AIL_DRIVER

The basic type AIL_DRIVER specifies a low-level digital or XMIDI DOS driver.

Group: Basic Types
Related Functions: AIL_install_driver


REALFAR

The basic type REALFAR specifies a lower 1 MB real mode address.

Group: Basic Types
Related Functions: AIL_get_real_vect, AIL_set_USE16_ISR, AIL_set_real_vect


LPDIRECTSOUND

The basic type LPDIRECTSOUND describes a pointer to a DirectSound object.

Group: Basic Types
Related Functions: AIL_get_DirectSound_info


LPDIRECTSOUNDBUFFER

The basic type LPDIRECTSOUNDBUFFER describes a pointer to a DirectSound buffer object.

Group: Basic Types
Related Functions: AIL_get_DirectSound_info


HWND

The basic type HWND specifies a Windows window handle.

Group: Basic Types
Related Functions: AIL_HWND, AIL_set_DirectSound_HWND


LPHWAVEOUT

The basic type LPHWAVEOUT specifies a pointer to a Windows waveOut device.

Group: Basic Types


LPHMIDIOUT

The basic type LPHMIDIOUT specifies a pointer to a Windows midiOut device.

Group: Basic Types
Related Functions: AIL_midiOutOpen


FSSpec

The basic type FSSpec is a MacOS file spec structure used on Classic and Carbon.

Group: Basic Types
Related Sections: Filenames on MacOS


VOID_PTR

The basic type VOID_PTR describes a standard C/C++ untyped memory pointer.

Group: Basic Types
Related Functions: RAD_IOPGetFileHandleToIOPMemory, RAD_IOPGetFileHandleToSPUMemory, RAD_IOPStartUp
Related Structures: RAD_IOP_ASYNC_READ_DATA, RAD_IOP_SOUND_DATA


CHAR_PTR

The basic type CHAR_PTR describes a normal zero-terminated C-style string.

Group: Basic Types
Related Structures: RAD_IOP_ASYNC_OPEN_DATA


Quick Integration Services

Discussion

The Quick Integration Services API is designed to let you get audio into your applications almost immediately.

Using the Quick API, you can usually be playing an audio sample (digital or MIDI in three or four function calls.

Generally, folks will use the Quick API to get up and running and then switch over to the full Miles API as time and/or feature requests demand.

Quick Integration Services
AIL_quick_startup | initializes the quick integration system.
MILES_QUICK_DIGITAL_OPEN | describes how to open the digital audio system.
MILES_QUICK_MIDI_OPEN | describes how to open the MIDI system.
AIL_quick_shutdown | closes the quick integration API.
AIL_quick_load | loads a sound file, returning a handle that can be used with the other quick API functions.
AIL_quick_fss_load | loads a sound file from a Mac file spec, returning a handle that can be used with the other quick API functions.
AIL_quick_load_mem | loads a sound file that is already loaded into memory, returning a handle that can be used with the other quick API functions.
AIL_quick_load_named_mem | loads a sound file that is already loaded into memory, with a filename hint, returning a handle that can be used with the other quick API functions.
AIL_quick_copy | copies an audio handle from an already-loaded audio handle.
AIL_quick_unload | unloads a sound handle previously loaded with AIL_quick_load or AIL_quick_load_and_play.
AIL_quick_play | starts the playback of an audio file previously loaded with AIL_quick_load.
AIL_quick_halt | stops a currently playing audio handle.
AIL_quick_status | returns the status of an audio handle.
MILES_QUICK_STATUS | describes the status of a Quick API audio handle.
AIL_quick_load_and_play | loads a sound file into a handle and begins playing it immediately.
AIL_quick_fss_load_and_play | loads a Mac file spec sound into a handle and begins playing it immediately.
AIL_quick_type | returns the type of an audio handle.
MILES_QUICK_TYPE | describes the data in a Quick API audio handle.
AIL_quick_set_volume | controls the volume of an audio handle.
AIL_quick_set_speed | controls the playback rate of an audio handle.
AIL_quick_ms_length | returns the total length in milliseconds of an audio handle.
AIL_quick_ms_position | returns the current position in milliseconds of an audio handle.
AIL_quick_set_ms_position | changes current playback position in milliseconds of the specified audio handle.
AIL_quick_set_reverb_levels | changes the reverb levels of a digital audio sample, or a MIDI playing through the software synthesizer.
AIL_quick_set_low_pass_cut_off | applies a low-pass filter to the digital audio sample.
AIL_quick_handles | returns the MSS digital driver and MIDI driver handles.


AIL_quick_startup

The function AIL_quick_startup initializes the quick integration system.

S32 AIL_quick_startup(
  S32 use_digital,
  S32 use_MIDI,
  U32 output_rate,
  S32 output_bits,
  S32 output_channels
);

In Parameters

use_digital
specifies whether you want to play digital sounds. Use one of the MILES_QUICK_DIGITAL_OPEN constants.
use_MIDI
specifies whether you want to play XMIDI files. Use one of the MILES_QUICK_MIDI_OPEN constants.
output_rate
specifies the desired digital audio output frequency rate (11025, 22050, etc.).
output_bits
specifies the desired digital audio output word size (8 or 16 bits).
output_channels
specifies the desired number of digital audio output channels (1 = mono, 2 = stereo, or an MSS_MC_SPEC enum value).

Returns

This function will return a non-zero value if the function succeeded. If it failed (zero return value), then AIL_last_error will contain the reason.

Discussion

This function must be called before any other quick API functions are used. You can use either the digital, XMIDI, or both systems simultaneously. You can pass in zeros for any of the output parameters, if you'd like MSS to choose the best value. Note that the output rate represents only the final output quality of the sound system - you can play any type of sound and MSS will convert it on-the-fly.

Call AIL_quick_shutdown to close the Quick Services.

You must call AIL_set_redist_directory to set your application's Miles directory before calling this function.

Under DOS, Wii, PS2 and MacOS 9, this function must not be invoked from an interrupt-based callback function.

Under the original Xbox, this function will open the DirectSound system.

The Xbox hardware always uses a fixed 48 Khz, 16-bit output, so the frequency, bits, and channels don't specify the output mode, but instead specify the default format of each sound buffer. You should set these parameters to those of the majority of your sound samples (if not, Miles will simply reset the format when you start the sound which is a little less efficient).

On the Xbox 360, this function will open the XAudio system.

On the Sony PS2, the driver is always opened in 48 kHz 16-bit stereo mode. The only meaningful channel configurations are MSS_MC_STEREO, MSS_MC_40_DTS, and MSS_MC_51_DTS.

On the Nintendo Wii, the driver is always opened in 32028 Hz 16-bit mode. Miles will use one or two AX voices.

On the Sony PS3, this function opens one of the libaudio ports for output. Miles for PS3 always uses 48 Khz, 32-bit floating point output.

Under MacOS, MSS will use the Sound Manager. There have been many versions of the Sound Manager, some of which behave better than others. If you have trouble, try downloading the latest version of QuickTime - this will get you the latest version of Sound Manager.

Under DOS, MSS will set the sound format preferences and then call AIL_install_DIG_INI to load a real-mode DOS driver.

For an understanding of the options available with the output_channels parameter, see the How do I use multi-channel sound output in Miles? FAQ.

Example files that use this function: Quick.C, Play.C

Group: Quick Integration Services
Related Sections: Miles DTS Provider for the Sony PS2, Miles Dolby Surround Provider, Miles SRS Circle Surround Provider
Related Functions: AIL_last_error, AIL_open_digital_driver, AIL_quick_handles, AIL_quick_shutdown, AIL_set_redist_directory, AIL_speaker_configuration, AIL_startup
Related Basic Types: MILES_QUICK_DIGITAL_OPEN, MILES_QUICK_MIDI_OPEN, MSS_MC_SPEC, S32, U32
Related FAQs: How do I initialize the Miles Sound System for use?, How do I use multi-channel sound output in Miles?


MILES_QUICK_DIGITAL_OPEN

The basic type MILES_QUICK_DIGITAL_OPEN describes how to open the digital audio system.

Fundamental Values

Value | Description
0 | Don't open digital audio at all.
1 | Open digital audio. On Win32/Win64, try DirectSound first, then try the waveOut drivers if DirectSound fails to load or is running in emulation mode.
AIL_QUICK_USE_WAVEOUT | Open digital audio, but force the use of the waveOut drivers on Win32 or Win64.

Group: Quick Integration Services
Related Functions: AIL_quick_startup


MILES_QUICK_MIDI_OPEN

The basic type MILES_QUICK_MIDI_OPEN describes how to open the MIDI system.

Fundamental Values

Value | Description
0 | Don't open the XMIDI system at all.
1 | Open the XMIDI system.
AIL_QUICK_MIDI_AND_DLS | Open the XMIDI system as well as the DLS software-synth.
AIL_QUICK_DLS_ONLY | Open the XMIDI system with the DLS software-synth only (no fallback to hardware MIDI).

Group: Quick Integration Services
Related Functions: AIL_quick_startup


AIL_quick_shutdown

The function AIL_quick_shutdown closes the quick integration API.

void AIL_quick_shutdown();

Discussion

If the call to AIL_quick_startup succeeded, then you must call this function before exiting your application. Failure to do so could cause your computer to lock up on some operating systems.

Under DOS, Wii, PS2 and MacOS 9, this function must not be invoked from an interrupt-based callback function.

Example files that use this function: Quick.C, Play.C

Group: Quick Integration Services
Related Functions: AIL_quick_startup, AIL_shutdown, AIL_startup
Related Basic Types: void
Related FAQs: How do I initialize the Miles Sound System for use?


AIL_quick_load

The function AIL_quick_load loads a sound file, returning a handle that can be used with the other quick API functions.

HAUDIO AIL_quick_load(
  char const * filename
);

In Parameters

filename
specifies the name of a .WAV, .MP3, .OGG, .VOC or .XMI file.

Returns

A new audio handle if the function was successful, NULL otherwise.

Discussion

This function can load Microsoft .WAV files (uncompressed, XMA, or IMA ADPCM compressed), MPEG Layer-3 files, Ogg Vorbis files, Creative Labs .VOC files, or XMIDI files.

You must call AIL_quick_unload on all handles returned by this function.

Under DOS and MacOS 9, this function must not be invoked from an interrupt-based callback function.

Example files that use this function: Quick.C, Play.C

Group: Quick Integration Services
Related Functions: AIL_quick_copy, AIL_quick_fss_load, AIL_quick_fss_load_and_play, AIL_quick_load_and_play, AIL_quick_load_mem, AIL_quick_load_named_mem, AIL_quick_unload
Related Basic Types: HAUDIO, char const *
Related FAQs: How do I play a digital sound?


AIL_quick_fss_load

The function AIL_quick_fss_load loads a sound file from a Mac file spec, returning a handle that can be used with the other quick API functions.

HAUDIO AIL_quick_fss_load(
  FSSpec const * file_spec
);

In Parameters

file_spec
specifies the FSSpec structure of a .WAV, .MP3, .OGG, .VOC or .XMI file.

Returns

A new audio handle if the function was successful, NULL otherwise.

Discussion

This function is only used on the Mac with the Classic or Carbon CFM libraries - the Mach-O version of Miles just uses normal Unix style slash separated string filenames. This function can load Microsoft .WAV files (uncompressed, XMA, or IMA ADPCM compressed), MPEG Layer-3 files, Ogg Vorbis files, Creative Labs .VOC files, or XMIDI files.

You must call AIL_quick_unload on all handles returned by this function.

This function must not be invoked from an interrupt-based callback function.

Group: Quick Integration Services
Related Sections: Filenames on MacOS
Related Functions: AIL_quick_copy, AIL_quick_fss_load_and_play, AIL_quick_load, AIL_quick_load_and_play, AIL_quick_load_mem, AIL_quick_unload
Related Basic Types: FSSpec, HAUDIO


AIL_quick_load_mem

The function AIL_quick_load_mem loads a sound file that is already loaded into memory, returning a handle that can be used with the other quick API functions.

HAUDIO AIL_quick_load_mem(
  void const * mem,
  U32 size
);

In Parameters

mem
specifies the address of a loaded .WAV, .MP3, .OGG, .VOC, .MID or .XMI file.
size
specifies the length of the data in bytes.

Returns

A new audio handle if the function was successful, NULL otherwise.

Discussion

This function can read Microsoft .WAV files, XMA- or IMA ADPCM-compressed .WAV files, MPEG Layer-3 files, Ogg Vorbis files, Creative Labs .VOC files, normal MIDI files, or XMIDI files.

You must call AIL_quick_unload on all handles returned by this function. The memory image provided to this function must not be freed until AIL_quick_unload has been called.

Under DOS and MacOS 9, this function must not be invoked from an interrupt-based callback function.

Example files that use this function: MilesPly.C

Group: Quick Integration Services
Related Functions: AIL_quick_copy, AIL_quick_fss_load, AIL_quick_fss_load_and_play, AIL_quick_load, AIL_quick_load_and_play, AIL_quick_unload
Related Basic Types: HAUDIO, U32, void const *


AIL_quick_load_named_mem

The function AIL_quick_load_named_mem loads a sound file that is already loaded into memory, with a filename hint, returning a handle that can be used with the other quick API functions.

HAUDIO AIL_quick_load_named_mem(
  void const * mem,
  char const * filename,
  U32 size
);

In Parameters

mem
specifies the address of a loaded .WAV, .MP3, .OGG, .VOC, .MID or .XMI file.
filename
specifies the filename of the data loaded at mem - this is used to load memory buffers of suond data that we can't positively identify without a filename hint (like voice chat buffers).
size
specifies the length of the data in bytes.

Returns

A new audio handle if the function was successful, NULL otherwise.

Discussion

This function can read Microsoft .WAV files, XMA- or IMA ADPCM-compressed .WAV files, MPEG Layer-3 files, Ogg Vorbis files, Voxware Voice chat compressed files, Creative Labs .VOC files, normal MIDI files, or XMIDI files.

You must call AIL_quick_unload on all handles returned by this function. The memory image provided to this function must not be freed until AIL_quick_unload has been called.

Under DOS and MacOS 9, this function must not be invoked from an interrupt-based callback function.

Example files that use this function: MilesPly.C

Group: Quick Integration Services
Related Functions: AIL_quick_copy, AIL_quick_load, AIL_quick_load_and_play, AIL_quick_unload
Related Basic Types: HAUDIO, U32, char const *, void const *


AIL_quick_copy

The function AIL_quick_copy copies an audio handle from an already-loaded audio handle.

HAUDIO AIL_quick_copy(
  HAUDIO audio
);

In Parameters

audio
is the handle you which to duplicate.

Returns

A new audio handle if the function was successful, NULL otherwise.

Discussion

This function lets you play a single audio file more than once. Note that only the header is actually copied - the digital sound or MIDI data is only loaded once.

You must call AIL_quick_unload on all handles returned by this function.

The memory containing the digital sound or MIDI data won't be freed until the original audio handle and all copied handles have been unloaded.

Under DOS and MacOS 9, this function must not be invoked from an interrupt-based callback function.

Group: Quick Integration Services
Related Functions: AIL_quick_fss_load, AIL_quick_fss_load_and_play, AIL_quick_load, AIL_quick_load_and_play, AIL_quick_load_mem, AIL_quick_load_named_mem, AIL_quick_unload
Related Basic Types: HAUDIO


AIL_quick_unload

The function AIL_quick_unload unloads a sound handle previously loaded with AIL_quick_load or AIL_quick_load_and_play.

void AIL_quick_unload(
  HAUDIO audio
);

In Parameters

audio
specifies the audio handle that you wish to unload.

Discussion

You must not use the sound handle after you have unloaded it.

This function should be called for all audio handles allocated with AIL_quick_load or AIL_quick_load_and_play.

If the handle is playing, it will be stopped before it is unloaded.

Under DOS and MacOS 9, this function must not be invoked from an interrupt-based callback function.

Example files that use this function: Quick.C, Play.C

Group: Quick Integration Services
Related Functions: AIL_quick_copy, AIL_quick_fss_load, AIL_quick_fss_load_and_play, AIL_quick_halt, AIL_quick_load, AIL_quick_load_and_play, AIL_quick_load_mem, AIL_quick_load_named_mem, AIL_quick_status
Related Basic Types: HAUDIO, void


AIL_quick_play

The function AIL_quick_play starts the playback of an audio file previously loaded with AIL_quick_load.

S32 AIL_quick_play(
  HAUDIO audio,
  U32 loop_count
);

In Parameters

audio
specifies the audio handle that you wish to play.
loop_count
specifies the number of times to loop the audio handle (use 0 to loop forever).

Returns

Whether the function succeeded or not.

Discussion

Once this function is called, AIL_quick_status will return QSTAT_PLAYING until the audio playback is completed. You can play an audio handle multiple times.

Example files that use this function: Quick.C

Group: Quick Integration Services
Related Functions: AIL_quick_fss_load_and_play, AIL_quick_halt, AIL_quick_load_and_play, AIL_quick_status
Related Basic Types: HAUDIO, MILES_QUICK_STATUS, S32, U32
Related FAQs: How do I play a digital sound?


AIL_quick_halt

The function AIL_quick_halt stops a currently playing audio handle.

void AIL_quick_halt(
  HAUDIO audio
);

In Parameters

audio
specifies the audio handle that you wish to stop.

Discussion

You can use this function to stop a looping audio handle.

Example files that use this function: Quick.C

Group: Quick Integration Services
Related Functions: AIL_quick_play, AIL_quick_status, AIL_quick_unload
Related Basic Types: HAUDIO, void


AIL_quick_status

The function AIL_quick_status returns the status of an audio handle.

S32 AIL_quick_status(
  HAUDIO audio
);

In Parameters

audio
specifies the audio handle that you wish to query.

Returns

This function will return one of the MILES_QUICK_STATUS constants.

Discussion

You can replay an audio handle that has the QSTAT_DONE status by calling the AIL_quick_play function.

Group: Quick Integration Services
Related Functions: AIL_quick_halt, AIL_quick_play, AIL_quick_unload
Related Basic Types: HAUDIO, MILES_QUICK_STATUS, S32


MILES_QUICK_STATUS

The basic type MILES_QUICK_STATUS describes the status of a Quick API audio handle.

Fundamental Values

Value | Description
QSTAT_DONE | Audio handle has finished playing or has been halted. (Debugger value: 1).
QSTAT_LOADED | Audio handle has been loaded, but not played yet. (Debugger value: 2).
QSTAT_PLAYING | Audio handle is currently playing. (Debugger value: 3).

Group: Quick Integration Services
Related Functions: AIL_quick_play, AIL_quick_status


AIL_quick_load_and_play

The function AIL_quick_load_and_play loads a sound file into a handle and begins playing it immediately.

HAUDIO AIL_quick_load_and_play(
  char const * filename,
  U32 loop_count,
  S32 wait_request
);

In Parameters

filename
specifies the name of a .WAV, .VOC, .MP3, .OGG, or .XMI file.
loop_count
specifies the number of times to loop the audio handle (use 0 to loop forever).
wait_request
specifies whether the function should wait until the playback is complete before returning.

Returns

A new audio handle if the function was successful, NULL otherwise.

Discussion

This function can load uncompressed Microsoft .WAV files, IMA ADPCM compressed .WAV files, Creative Labs .VOC files, Ogg Vorbis files, MPEG Layer 3 files, or XMIDI files. This function will begin playback immediately (unlike AIL_quick_load ).

You must call AIL_quick_unload on all handles returned by this function.

Under DOS and MacOS 9, this function must not be invoked from an interrupt-based callback function.

Group: Quick Integration Services
Related Functions: AIL_quick_copy, AIL_quick_fss_load, AIL_quick_load, AIL_quick_load_mem, AIL_quick_load_named_mem, AIL_quick_play, AIL_quick_unload
Related Basic Types: HAUDIO, S32, U32, char const *


AIL_quick_fss_load_and_play

The function AIL_quick_fss_load_and_play loads a Mac file spec sound into a handle and begins playing it immediately.

HAUDIO AIL_quick_fss_load_and_play(
  FSSpec const * file_spec,
  U32 loop_count,
  S32 wait_request
);

In Parameters

file_spec
specifies the a Mac FSSpec structure of a .WAV, .VOC, .MP3, .OGG, or .XMI file.
loop_count
specifies the number of times to loop the audio handle (use 0 to loop forever).
wait_request
specifies whether the function should wait until the playback is complete before returning.

Returns

A new audio handle if the function was successful, NULL otherwise.

Discussion

This function is only used on the Mac with the Classic or Carbon CFM libraries - the Mach-O version of Miles just uses normal Unix style slash separated string filenames.

This function can load uncompressed Microsoft .WAV files, IMA ADPCM compressed .WAV files, Creative Labs .VOC files, Ogg Vorbis files, MPEG Layer 3 files, or XMIDI files. This function will begin playback immediately (unlike AIL_quick_fss_load ).

You must call AIL_quick_unload on all handles returned by this function.

This function must not be invoked from an interrupt-based callback function.

Group: Quick Integration Services
Related Sections: Filenames on MacOS
Related Functions: AIL_quick_copy, AIL_quick_fss_load, AIL_quick_load, AIL_quick_load_mem, AIL_quick_play, AIL_quick_unload
Related Basic Types: FSSpec, HAUDIO, S32, U32


AIL_quick_type

The function AIL_quick_type returns the type of an audio handle.

S32 AIL_quick_type(
  HAUDIO audio
);

In Parameters

audio
specifies the audio handle that you wish to query.

Returns

This function will return one of the MILES_QUICK_TYPE constants.

Group: Quick Integration Services
Related Basic Types: HAUDIO, MILES_QUICK_TYPE, S32


MILES_QUICK_TYPE

The basic type MILES_QUICK_TYPE describes the data in a Quick API audio handle.

Fundamental Values

Value | Description
AIL_QUICK_XMIDI_TYPE | Audio handle contains MIDI or XMIDI data. (Debugger value: 1).
AIL_QUICK_DLS_XMIDI_TYPE | Audio handle contains MIDI or XMIDI data with embedded DLS data. (Debugger value: 3).
AIL_QUICK_DIGITAL_TYPE | Audio handle contains digital sound data. (Debugger value: 2).
AIL_QUICK_MPEG_DIGITAL_TYPE | Audio handle contains MPEG digital sound data. (Debugger value: 4).
AIL_QUICK_OGG_VORBIS_TYPE | Audio handle contains Ogg Vorbis digital sound data. (Debugger value: 5).

Group: Quick Integration Services
Related Functions: AIL_quick_type


AIL_quick_set_volume

The function AIL_quick_set_volume controls the volume of an audio handle.

void AIL_quick_set_volume(
  HAUDIO audio,
  F32 volume,
  F32 extra
);

In Parameters

audio
specifies the audio handle that you wish to control.
volume
specifies the new volume level (0 to 1.0).
extra
specifies the extra volume information. For audio handles containing digital data, this is the pan setting (0-1.0: 0.0 is hard left, 1.0 is hard right). For audio handles containing MIDI data, this is the delay time over which the requested volume-scaling takes place.

Discussion

You can use this function even if you haven't started playback yet.

Group: Quick Integration Services
Related Functions: AIL_quick_set_speed
Related Basic Types: F32, HAUDIO, void


AIL_quick_set_speed

The function AIL_quick_set_speed controls the playback rate of an audio handle.

void AIL_quick_set_speed(
  HAUDIO audio,
  S32 speed
);

In Parameters

audio
specifies the audio handle that you wish to control.
speed
specifies the new playback speed. For audio handles containing digital data, this is the playback rate (11025, 22050, etc). For audio handles containing MIDI data, this is the tempo percentage (see AIL_set_sequence_tempo ).

Discussion

You can use this function even if you haven't started playback yet.

Group: Quick Integration Services
Related Functions: AIL_quick_set_volume, AIL_set_sequence_tempo
Related Basic Types: HAUDIO, S32, void


AIL_quick_ms_length

The function AIL_quick_ms_length returns the total length in milliseconds of an audio handle.

S32 AIL_quick_ms_length(
  HAUDIO audio
);

In Parameters

audio
specifies the audio handle that you wish to query.

Returns

The length in milliseconds.

Group: Quick Integration Services
Related Functions: AIL_quick_ms_position, AIL_quick_set_ms_position
Related Basic Types: HAUDIO, S32


AIL_quick_ms_position

The function AIL_quick_ms_position returns the current position in milliseconds of an audio handle.

S32 AIL_quick_ms_position(
  HAUDIO audio
);

In Parameters

audio
specifies the audio handle that you wish to query.

Returns

The current playback position.

Group: Quick Integration Services
Related Functions: AIL_quick_ms_length, AIL_quick_set_ms_position
Related Basic Types: HAUDIO, S32


AIL_quick_set_ms_position

The function AIL_quick_set_ms_position changes current playback position in milliseconds of the specified audio handle.

void AIL_quick_set_ms_position(
  HAUDIO audio,
  S32 milliseconds
);

In Parameters

audio
specifies the audio handle that you wish to control.
milliseconds
specifies the new position in milliseconds.

Discussion

You can use this function even if you haven't started playback yet.

Group: Quick Integration Services
Related Functions: AIL_quick_ms_length, AIL_quick_ms_position
Related Basic Types: HAUDIO, S32, void


AIL_quick_set_reverb_levels

The function AIL_quick_set_reverb_levels changes the reverb levels of a digital audio sample, or a MIDI playing through the software synthesizer.

void AIL_quick_set_reverb_levels(
  HAUDIO audio,
  F32 dry_level,
  F32 wet_level
);

In Parameters

audio
specifies the audio handle that you wish to control.
dry_level
specifies the level of the dry sound signal (the non-reverbed sound). The range is 0.0 for no output, 1.0 for full output.
wet_level
specifies the level of the wet sound signal (the reverberations). The range is 0.0 for no output, 1.0 for full output.

Discussion

This function controls the reverb levels applied by the AIL_set_digital_master_reverb.

These levels are linear scalars, where each doubling of the level value represents a 6-dB change in the wet or dry level. For instance, a wet_level or dry_level value of 0.5 is 6 dB quieter than a value of 1.0, and 0.25 would be 12 dB quieter than 1.0.

Reverb requires CPU time to apply, but it's pretty minimal. You can monitor the CPU use with the AIL_digital_CPU_percent function.

You can use this function even if you haven't started playback yet. This function will have no effect with per-voice hardware drivers that don't support reverb in hardware. Currently, this applies only to the MSS_MC_DIRECTSOUND3D value from the MSS_MC_SPEC list, since the EAX providers handle reverb directly and the software-mixing options emulate EAX.

Group: Quick Integration Services
Related Functions: AIL_digital_CPU_percent, AIL_set_digital_master_reverb
Related Basic Types: F32, HAUDIO, MSS_MC_SPEC, void


AIL_quick_set_low_pass_cut_off

The function AIL_quick_set_low_pass_cut_off applies a low-pass filter to the digital audio sample.

void AIL_quick_set_low_pass_cut_off(
  HAUDIO audio,
  F32 cut_off
);

In Parameters

audio
specifies the audio handle that you wish to control (must be a digital handle).
cut_off
specifies the low-pass filter cutoff frequency. The range is 0.0 to 1.0, given as a fraction of the sample's Nyquist rate (which is half the sample rate). For example, if you have a 44100 Hz sample, then the Nyquist rate is 22050 Hz. If you then set a 0.5 cutoff factor, only frequencies under 11025 Hz will be perceived at close to their full amplitude.

Note that the original Xbox's low-pass filter hardware is limited to 30 Hz to 8000 Hz.

Discussion

This function allows you to set a low-pass filter on any digital sample (whether uncompressed or compressed). A low-pass filter attenuates frequencies above the cutoff frequency.

The default low-pass cutoff is 1.0 (allowing all frequencies to pass).

There is almost no CPU hit at all with this filter. There is no CPU hit at all on the original Xbox, but the hardware low-pass filter only supports frequencies from 30 to 8000 Hz.

Group: Quick Integration Services
Related Basic Types: F32, HAUDIO, void


AIL_quick_handles

The function AIL_quick_handles returns the MSS digital driver and MIDI driver handles.

void AIL_quick_handles(
  HDIGDRIVER *dig,
  HMDIDRIVER *mdi,
  HDLSDEVICE *dls
);

Out Parameters

dig
specifies the location to store the digital driver handle.
mdi
specifies the location to store the MIDI driver handle.
dls
specifies the location to store the DLS device handle.

Discussion

You can then use these handles with the full API functions.

This function lets you use the quick API to initialize MSS, but still use the full API in the rest of your application.

Group: Quick Integration Services
Related Functions: AIL_DLS_open, AIL_open_XMIDI_driver, AIL_open_digital_driver, AIL_quick_startup
Related Basic Types: HDIGDRIVER, HDLSDEVICE, HMDIDRIVER, void


System Services

Discussion

The Systems Services include the functions to control the environment, startup, and shutdown of the Miles library.

System Services
AIL_set_redist_directory | sets the location of your application's Miles directory.
Register_RIB | registers a static library RIB interface on non-Win32 platforms such as Xbox, Sony Playstation 2 or DOS.
AIL_startup | initializes the Miles Sound System and prepares for the installation and use of sound drivers.
AIL_shutdown | shuts down all active sound drivers, restores normal system timer operation, and disconnects the API timer interrupt handler.
AIL_MSS_version | returns the version of the Miles library.
AIL_serve | provides periodic foreground service to the Miles Sound System to avoid `starvation` during periods when the application does not yield control frequently.
AIL_set_preference | controls certain internal parameters used by the MSS system.
AIL_get_preference | queries the current MSS internal parameters.
AIL_last_error | returns a string describing the last MSS error.
AIL_background | allows an application function to determine if it is currently running in `background` mode from an interrupt or thread, or if it is currently running in the `foreground`.
AIL_register_trace_callback | registers an application function to receive debug trace message traffic from MSS.
AILTRACECB | specifies a user-defined debug-trace callback.
AIL_platform_property | retrieves and/or sets platform-specific properties for the Miles Sound System.
MSS_PLATFORM_PROPERTY | is a list of available platform-specific property identifiers for use with the AIL_platform_property function.


AIL_set_redist_directory

The function AIL_set_redist_directory sets the location of your application's Miles directory.

char * AIL_set_redist_directory(
  char const * directory
);

In Parameters

directory

Returns

The new directory path.

Discussion

Under Windows, this directory should contain the Miles ASI and FLT providers. Under MacOS, this directory should contain the Miles shared libraries. Under DOS, this directory should contain the sound drivers (*.DIG, *.MDI).

Miles always first loads the ASI and FLT providers from the directory containing MSS32.DLL. After the default directory is searched, then the redistribution directory is scanned.

Normally, the redistribution directory is relative to the location of the Miles library file, so if you are using a relative path - make sure it is relative to the location of the Miles library. You can tell Miles to use a redistribution directory relative to the current directory when AIL_startup is called by placing a "*" in front of the redistribution directory ("*redist" instead of "redist", for example).

You must call AIL_set_redist_directory to set your application's Miles directory before calling AIL_startup or AIL_quick_startup.

On MacOS under Classic and Carbon CFM, you use ":" separated directory names (like ":redist:classic"). On Carbon Mach-O, you just use normal Unix style pathnames (like "redist/macho").

Group: Digital Filter Services, System Services
Related Functions: AIL_init_sequence, AIL_install_DIG_INI, AIL_install_DIG_driver_file, AIL_install_DIG_driver_image, AIL_install_MDI_INI, AIL_install_MDI_driver_file, AIL_install_MDI_driver_image, AIL_install_timbre, AIL_quick_startup, AIL_set_GTL_filename_prefix, AIL_set_named_sample_file, AIL_set_redist_directory, AIL_startup
Related Basic Types: char, char *, char const *
Related FAQs: How do I initialize the Miles Sound System for use?, How do I use a Unicode path on Windows?, I can't get Miles to play an MP3, XMA, or Ogg Vorbis file - what's going on?


Register_RIB

The function Register_RIB registers a static library RIB interface on non-Win32 platforms such as Xbox, Sony Playstation 2 or DOS.

void Register_RIB(
  void * static_lib_name
);

In Parameters

static_lib_name
Name of the static RIB library to load.

Discussion

On the static library versions of Miles (Xbox, Wii, PS2, PS3 and DOS), you must manually load the ASI decompressors that you want to use.

This function (macro actually) takes a single paramater - the static library to load. Currently, the available static libraries include MP3Dec, OggDec, Voice, SRS, DolbySurround, and DSP. To load any or all of these libraries, you use this function before AIL_startup. For example:

Register_RIB(MP3Dec);
Register_RIB(DSP);
Register_RIB(Voice);
Register_RIB(XMADec);
Register_RIB(OGGDec);
AIL_startup();

Group: System Services
Related Sections: Integrating Miles into a Nintendo Wii Build Environment, Integrating Miles into a PlayStation 2 Build Environment, Integrating Miles into a PlayStation 3 Build Environment, Integrating Miles into a Xbox 360 Build Environment
Related Functions: AIL_startup
Related Basic Types: void, void *
Related FAQs: How do I initialize the Miles Sound System for use?


AIL_startup

The function AIL_startup initializes the Miles Sound System and prepares for the installation and use of sound drivers.

S32 AIL_startup();

Returns

Non-zero if the library was initialized by the current call to AIL_startup, or zero if the library was initialized by an earlier call to AIL_startup.

Discussion

This function must be called before any other API functions except AIL_set_redist_directory and Register_RIB are used. You can call this function multiple times, but the system will only be initialized the first time.

On Win32, Win64, MacOS and Linux, you must call AIL_set_redist_directory to set your application's Miles directory before calling this function. On all platforms except those that support x86 (Win32) DLLs, you should call Register_RIB to load any static filters or decompressors that your application needs before calling AIL_startup.

You can also call AIL_quick_startup and AIL_quick_shutdown to initialize and shut down the Miles system. However, note that you must call AIL_shutdown to shut down the library if it was originally initialized by AIL_startup.

Under DOS, Wii, PS2 and MacOS 9, this function must not be invoked from an interrupt-based callback function.

Example files that use this function: All

Group: Digital Filter Services, System Services
Related Sections: Miles DTS Provider for the Sony PS2
Related Functions: AIL_last_error, AIL_mem_use_free, AIL_mem_use_malloc, AIL_quick_shutdown, AIL_quick_startup, AIL_register_trace_callback, AIL_set_named_sample_file, AIL_set_redist_directory, AIL_set_timer_divisor, AIL_set_timer_frequency, AIL_set_timer_period, AIL_shutdown, AIL_startup, Register_RIB
Related Basic Types: MILES_PREFERENCES, S32
Related FAQs: How do I initialize the Miles Sound System for use?, How do I use a Unicode path on Windows?, I'm setting a preference and it isn't having any effect - what's going on?


AIL_shutdown

The function AIL_shutdown shuts down all active sound drivers, restores normal system timer operation, and disconnects the API timer interrupt handler.

void AIL_shutdown();

Discussion

Like AIL_startup, this function can be called multiple times, but it is the first call that actually shuts down the system. After calling AIL_shutdown once, you must be careful not to call any other MSS functions until you call AIL_startup again.

If you are using the Quick Integration Services, then you should use AIL_quick_shutdown instead of this function.

All application timers are stopped and released by this function, and all drivers are shut down. There is no need to call AIL_release_timer_handle, or AIL_close_digital_driver/AIL_close_XMIDI_driver to shut down any active timers or drivers, if AIL_shutdown is called.

DOS applications which fail to call AIL_shutdown prior to termination may cause abnormal system behavior when starting up subsequent applications. This is because the INT 8 system timer-tick vector is captured by the MSS system when AIL_startup is called. The interrupt vector is not restored to its previous state until AIL_shutdown is called.

Under DOS, Wii, PS2 and MacOS 9, this function must not be invoked from an interrupt-based callback function.

Example files that use this function: All

Group: System Services
Related Functions: AIL_close_XMIDI_driver, AIL_close_digital_driver, AIL_quick_shutdown, AIL_release_timer_handle, AIL_shutdown, AIL_startup, AIL_stop_timer
Related Basic Types: void
Related FAQs: How careful do I have to be when shutting down?, How do I initialize the Miles Sound System for use?


AIL_MSS_version

The function AIL_MSS_version returns the version of the Miles library.

void AIL_MSS_version(
  char *dest,
  U32 len
);

In Parameters

len
specifies the length of the destination buffer.

Out Parameters

dest
specifies the destination buffer to place the version string.

Discussion

Under Windows and MacOS, this macro uses a resource call to extract the version to avoid calling into the library directly, so it is safe to call even if the library is completely different.

Under DOS, this calls into the Miles library.

Group: System Services
Related Basic Types: U32, char, void
Related FAQs: How can I tell what version of Miles that I have?


AIL_serve

The function AIL_serve provides periodic foreground service to the Miles Sound System to avoid "starvation" during periods when the application does not yield control frequently.

void AIL_serve();

Discussion

Under Windows, you only need to call this function when you won't be yielding to the Windows messaging system regularly. So, if you have a situation where you won't be calling PeekMessage or GetMessage, then you should try to call this function more than 5 times a second, but less than 20 times a second. If you call this function less than 5 times a second, the system can starve and sound will start breaking up. If you call this function more than 20 times a second, then system performance will be adversely affected.

At typical output sample rates, the Windows MSS digital audio system can maintain background playback for at least 500 milliseconds without receiving foreground timer service internally. Applications which need to continue digital audio playback during disk access, movie playback or other situations which tend to "starve" the Windows message queue should call AIL_serve as frequently as possible to help avoid sound dropouts.

Under MacOS, this function will pump the QuickTime MIDI services, if you are currently playing a MIDI file through QuickTime.

Under MacOS 9, this function must not be invoked from an interrupt-based callback function.

You may have to use this function periodically under Win32 when reading huge amounts of data off a CD-ROM or hard-drive that is still using a 16-bit driver.

This function is not supported under DOS.

Group: System Services
Related Sections: Sharing the CPU under MacOS
Related Functions: AIL_auto_service_stream, AIL_get_timer_highest_delay, AIL_serve, AIL_service_stream
Related Basic Types: MILES_PREFERENCES, void
Related FAQs: My sound is skipping on Windows or MacOS X - what can I do?


AIL_set_preference

The function AIL_set_preference controls certain internal parameters used by the MSS system.

SINTa AIL_set_preference(
  U32 name,
  SINTa value
);

In Parameters

name
specifies one of the MILES_PREFERENCES to set.
value
specifies the desired preference value.

Returns

The preference value which was previously in effect.

Discussion

See the Preferences section for information on the meaning of various preference names and the effects their preference values have on the MSS system and drivers.

Example files that use this function: SSTEST.C

Group: Preferences, System Services
Related Functions: AIL_allocate_sample_handle, AIL_allocate_sequence_handle, AIL_get_preference, AIL_set_sample_playback_rate
Related Basic Types: MILES_PREFERENCES, SINTa, U32
Related FAQs: My sound is skipping on Windows or MacOS X - what can I do?


AIL_get_preference

The function AIL_get_preference queries the current MSS internal parameters.

SINTa AIL_get_preference(
  U32 name
);

In Parameters

name
specifies one of the MILES_PREFERENCES to query.

Returns

The current preference value.

Discussion

See the Preferences section for information on the meaning of various preference names and the effects their preference values have on the MSS system and drivers.

Group: Preferences, System Services
Related Functions: AIL_set_preference
Related Basic Types: MILES_PREFERENCES, SINTa, U32


AIL_last_error

The function AIL_last_error returns a string describing the last MSS error.

char * AIL_last_error();

Returns

A pointer to the MSS error string.

Discussion

If no errors have occurred since AIL_startup was called, the MSS error string's first byte will be 0, indicating an empty string.

Example files that use this function: DEMO.C

Group: System Services
Related Functions: AIL_file_fss_read, AIL_file_read, AIL_init_sample, AIL_init_sequence, AIL_midiOutOpen, AIL_open_XMIDI_driver, AIL_open_digital_driver, AIL_quick_startup, AIL_startup
Related Basic Types: char, char *


AIL_background

The function AIL_background allows an application function to determine if it is currently running in "background" mode from an interrupt or thread, or if it is currently running in the "foreground".

S32 AIL_background();

Returns

0 if the application function which called AIL_background is currently running in the foreground. Otherwise, the application function is currently being executed within an MSS timer, XMIDI, or digital sound callback interrupt handler.

Discussion

Application functions which can be executed in both foreground and background contexts may call AIL_background to determine if a certain action is "safe" in the current context.

Most MSS functions can be safely invoked from within timer callback functions. Exceptions include driver-installation or driver-shutdown functions and any other functions which may perform DOS or BIOS calls, such as AIL_init_sequence. These exceptions are noted in the descriptions of the functions involved. If in doubt about whether a particular action may safely be performed from within a callback function, contact RAD Game Tools for assistance.

Group: System Services
Related Functions: AIL_background, AIL_init_sequence
Related Basic Types: S32


AIL_register_trace_callback

The function AIL_register_trace_callback registers an application function to receive debug trace message traffic from MSS.

AILTRACECB AIL_register_trace_callback(
  AILTRACECB callback,
  S32 level
);

In Parameters

callback
should be set to the address of an application function prototyped as an AILTRACECB callback.
level
specifies whether only application calls to Miles (1), application calls plus any resulting internal calls to Miles functions (2), or no calls at all (0) are reported to the trace callback.

Returns

The address of the previously-installed debug trace function handler.

Discussion

This function is intended primarily for use in diagnostic work. It provides a single convenient hook point that a Miles application can use to inspect its own calls to the system, and (optionally) any further calls to MSS that are made internally in the course of executing a given Miles function.

The ASCII text traffic which will be passed to the AILTRACECB callback function may consist of indenting whitespace, timestamps and other marker/decorative characters as well as function names, parameters, and return values.

Most applications that use AIL_register_trace_callback should pass 1 as the level parameter, to avoid excessive output-text clutter due to nested calls.

Background function calls (those made while Miles is executing from its own internal thread(s) or interrupt handlers) will not be reported to the trace callback.

AIL_startup must be called prior to registering a debug trace callback.

Group: System Services
Related Sections: Call Logging under DOS, Call Logging under MacOS, Call Logging under Nintendo, Call Logging under PlayStation 2, Call Logging under PlayStation 3, Call Logging under Win32, Call Logging under Win64, Call Logging under Xbox, Call Logging under Xbox 360
Related Functions: AILTRACECB, AIL_register_trace_callback, AIL_startup
Related Basic Types: S32


AILTRACECB

The function AILTRACECB specifies a user-defined debug-trace callback.

void AILCALLBACK AILTRACECB(
  char * text,
  S32 nest_depth
);

In Parameters

text
specifies a zero-terminated ASCII string bearing call-trace information or formatting.
nest_depth
indicates the call-nesting depth within the MSS API.

Discussion

The nest_depth parameter will be 1 for MSS calls which are made by the application itself, or a higher number for subsequent calls which are made from within MSS on behalf of the application-called function. (These nested calls will be reported only if AIL_register_trace_callback was invoked with a level parameter of 2.)

The ASCII text traffic which will be passed to the AILTRACECB callback function may consist of indenting whitespace, timestamps and other marker/decorative characters as well as function names, parameters, and return values.

Background function calls (those made while Miles is executing from its own internal thread(s) or interrupt handlers) will not be reported to the trace callback.

Group: System Services
Related Functions: AIL_register_trace_callback
Related Basic Types: S32, char *, void


AIL_platform_property

The function AIL_platform_property retrieves and/or sets platform-specific properties for the Miles Sound System.

S32 AIL_platform_property(
  void object,
  MSS_PLATFORM_PROPERTY property,
  void *before_value,
  void const * new_value,
  void *after_value
);

In Parameters

object
where required, indicates the HDIGDRIVER, HSAMPLE, or other MSS object handle whose platform-specific properties are to be accessed.
property
specifies which platform-specific property is to be retrieved or set.
new_value
is a pointer to a new value to set. If you don't want to set the property, pass in 0.

Out Parameters

before_value
is a pointer to a variable that will contain the property value before changing it. Always use this pointer to retrieve read-only properties. You can use 0 if you don't want to retrieve the prior value.
after_value
is a pointer to a variable that will contain the property value after changing it. You can use 0 if you don't want to retrieve the post-value.

Returns

Non-zero for success, 0 for failure.

Discussion

Applications which need to access internal MSS objects such as thread and window handles and DirectSound buffers may use this function to query and (in some cases) modify these object values. See the MSS_PLATFORM_PROPERTY type for a list of properties available under various platforms supported by Miles.

Most applications do not need to use this function. Unpredictable and difficult-to-troubleshoot consequences may arise from careless use of AIL_platform_property!

Group: System Services
Related Functions: AIL_platform_property
Related Basic Types: MSS_PLATFORM_PROPERTY, S32, void, void const *


MSS_PLATFORM_PROPERTY

The basic type MSS_PLATFORM_PROPERTY is a list of available platform-specific property identifiers for use with the AIL_platform_property function.

Fundamental Values

Value | Description
WIN32_TIMER_THREAD | Windows Read-only property returning the HANDLE to the thread used by Miles for all of its background mixing, callback, and user timer function processing. The object parameter is ignored. May be queried only after the first MSS timer function has been registered (typically by opening a digital or XMIDI driver).
WIN32_STREAM_THREAD | Windows Read-only property returning the HANDLE to the thread used by Miles do perform background disk IO for the streaming API. The object parameter is ignored. May be queried after the first stream is opened.
WIN32_HWAVEOUT | Windows Read-only property returning the HWAVEOUT handle to the waveOut audio driver in use, or NULL if DirectSound is in use. The object parameter should be an HDIGDRIVER handle to a digital driver open in waveOut mode.
WIN32_HWAVEIN | Windows Read-only property returning the HWAVEIN handle to the waveIn audio driver opened by the AIL_open_input function. The object parameter should be a valid HDIGINPUT handle returned by AIL_open_input.
WIN32_LPDS | Windows Read-only property corresponding to the IDirectSound object used by an HDIGDRIVER. The object parameter should be an HDIGDRIVER handle to a digital driver open in DirectSound mode.
WIN32_LPDSB | Windows Read-only property corresponding to the IDirectSoundBuffer object used by an HDIGDRIVER as its mixer target buffer. The object parameter should be an HDIGDRIVER handle to a digital driver open in DirectSound mode. Because a DirectSoundBuffer object may not be assigned until a sample or stream is actually played, you must play at least one sample or stream before querying this property.
WIN32_HWND | Windows Readable/writable property corresponding to the HWND that MSS will pass to DirectSound when establishing focus control in future calls to AIL_open_digital_driver. The object parameter is ignored and should be NULL. (Altering the WIN32_HWND property is necessary only if MSS guesses incorrectly when it tries to locate your application's main window).
XB_TIMER_THREAD | Xbox 1 Read-only property returning the HANDLE to the thread used by Miles to perform all background audio, user-timer, and callback processing. This thread is also used to service the XBox hardware mixer. The object parameter is ignored. May be queried only after the first MSS timer function has been registered (typically by opening a digital or XMIDI driver).
XB_STREAM_THREAD | Xbox 1 Read-only property returning the HANDLE to the thread used by Miles do perform background disk IO for the streaming API. The object parameter is ignored. May be queried after the first stream is opened.
XB_LPDS | Xbox 1 Read-only property corresponding to the IDirectSound object used by an HDIGDRIVER. The object parameter should be an HDIGDRIVER handle to a digital driver open in DirectSound mode.
XB_LPDSB | Xbox 1 Read-only property corresponding to the IDirectSoundBuffer object used by an HSAMPLE as its output target buffer. The object parameter should be the HSAMPLE to query. On the Xbox 1, DirectSoundBuffer objects are allocated by AIL_open_digital_driver, so it is not necessary to play any sounds before querying this property.
XB360_TIMER_THREAD | Xbox 360 Read-only property returning the HANDLE to the thread used by Miles for all of its background mixing, callback, and user timer function processing. The object parameter is ignored. May be queried only after the first MSS timer function has been registered (typically by opening a digital or XMIDI driver).
XB360_STREAM_THREAD | Xbox 360 Read-only property returning the HANDLE to the thread used by Miles do perform background disk IO for the streaming API. The object parameter is ignored. May be queried after the first stream is opened.
XB360_LPXAB | Xbox 360 Read-only property corresponding to the IXAudioSourceVoice object used by an HDIGDRIVER as its mixer target buffer. The object parameter should be an HDIGDRIVER handle to a digital driver. Because an IXAudioSourceVoice object may not be assigned to the driver until a sample or stream is actually played, you must play at least one sample or stream before querying this property.
PS3_TIMER_THREAD | PS3 Read-only property returning the HANDLE to the thread used by Miles for all of its background mixing, callback, and user timer function processing. The object parameter is ignored. May be queried only after the first MSS timer function has been registered (typically by opening a digital or XMIDI driver).
PS3_STREAM_THREAD | PS3 Read-only property returning the HANDLE to the thread used by Miles do perform background disk IO for the streaming API. The object parameter is ignored. May be queried after the first stream is opened.
PS3_AUDIO_PORT | PS3 Read-only property corresponding to the cellAudio port used by an HDIGDRIVER as its mixer target buffer. The object parameter should be an HDIGDRIVER handle to a digital driver.
PS3_AUDIO_ADDRESS | PS3 Read-only property corresponding to the memory address of the cellAudio sound buffer used by an HDIGDRIVER as its mixer target buffer. The object parameter should be an HDIGDRIVER handle to a digital driver.
PS3_AUDIO_LENGTH | PS3 Read-only property corresponding to the length of the cellAudio sound buffer used by an HDIGDRIVER as its mixer target buffer. The object parameter should be an HDIGDRIVER handle to a digital driver.
PS3_AUDIO_POSITION | PS3 Read-only property corresponding to the current position offset within the cellAudio sound buffer used by an HDIGDRIVER as its mixer target buffer. The object parameter should be an HDIGDRIVER handle to a digital driver.

Discussion

Before calling AIL_platform_property for any of these values, be sure you understand what object parameter (if any) is required to access the property, when the property value may be queried or modified, and how long it will remain valid. Most applications should not attempt to use MSS_PLATFORM_PROPERTY values or the AIL_platform_property function.

Group: System Services
Related Functions: AIL_open_digital_driver, AIL_open_input, AIL_platform_property


Memory and File Services

Discussion

The Memory and File Services are cross-platform services to control memory allocation and file I/O. On some platforms, memory must be allocated correctly for MSS use:

On Win32 and Win64, you don't need to anything special to the memory - you can use normal memory.

On MacOS, you must call AIL_mem_alloc_lock and AIL_mem_free_lock to manage memory that will be passed into MSS.

On DOS, you must call AIL_mem_alloc_lock and AIL_mem_free_lock or you must call AIL_vmm_lock to lock addresses that will be passed into MSS.

Memory and File Services
AIL_mem_alloc_lock | allocates a locked block of memory.
AIL_mem_free_lock | frees a pointer previously allocated with AIL_mem_alloc_lock or AIL_file_read.
AIL_file_read | loads a data file into the specified memory address, optionally allocating the memory as well.
AIL_file_fss_read | loads a data file spec into the specified memory address, optionally allocating the memory as well.
AIL_file_write | creates a new data file and fills it with the specified data.
AIL_file_fss_write | creates a new MacOS data file spec and fills it with the specified data.
AIL_file_fss_attrib_write | creates a new MacOS data file spec and fills it with the specified data.
AIL_WAV_file_write | creates a new Microsoft .WAV file.
AIL_WAV_file_fss_write | creates a new MacOS .WAV file spec.
AIL_file_size | returns the size of the specified data file.
AIL_file_fss_size | returns the size of the specified MacOS data file spec.
AIL_file_error | returns the last file I/O error from AIL_file_read, AIL_file_write, or AIL_file_size.
MILES_FILE_ERRORS | describes an error encountered by one of the Miles file I/O functions.
AIL_mem_use_malloc | replaces the default memory allocation routines.
AIL_mem_use_free | replaces the default memory freeing routine.
AILMALLOCCB | specifies a pointer to a user-defined memory allocation callback.
AILFREECB | specifies a pointer to a user-defined memory release callback.
AIL_set_file_callbacks | replaces the synchronous (blocking) file I/O functions that Miles uses for AIL_file_read, AIL_file_size, and the high-level streaming functions.
AIL_set_file_async_callbacks | replaces the file I/O handlers that Miles uses for its high-level streaming functions on certain platforms.
AIL_file_open_callback | specifies a user-replaceable callback handler to open a file in MSS.
AIL_file_close_callback | specifies a user-replaceable callback handler to close a file.
AIL_file_seek_callback | specifies a user-replaceable callback handler to seek in a file.
MILES_FILE_SEEK_TYPE | describes the type of seek to perform.
AIL_file_read_callback | specifies a user-replaceable callback handler to read from a file.
AIL_file_async_read_callback | specifies a user-replaceable callback handler to initiate asynchronous reads from a file.
AIL_file_async_status_callback | specifies a user-replaceable callback handler to poll for completion of an asynchronous read.
AIL_vmm_lock | locks the specified memory range under DOS.
AIL_vmm_unlock | unlocks a piece of memory previously locked with AIL_vmm_lock.
AIL_vmm_lock_range | locks the specified memory range under DOS.
AIL_vmm_unlock_range | unlocks a piece of memory previously locked with AIL_vmm_lock_range.


AIL_mem_alloc_lock

The function AIL_mem_alloc_lock allocates a locked block of memory.

void * AIL_mem_alloc_lock(
  U32 size
);

In Parameters

size
specifies the size of the block of memory that you need.

Returns

The pointer to the new block of memory, or NULL if the allocation failed.

Discussion

Under standard Windows platforms (Windows 9x, Windows NT), you don't have to use this function - you can just use normal memory.

Under DOS, you should use this function, or the AIL_vmm_lock functions, to ensure that the memory is available at interrupt time.

Under DOS and MacOS 9, this function must not be invoked from an interrupt-based callback function.

Example files that use this function: DEMO.C

Group: Memory and File Services
Related Sections: Memory management under Win32, Memory management under Win64
Related Functions: AIL_file_fss_read, AIL_file_read, AIL_mem_free_lock, AIL_mem_use_malloc, AIL_vmm_lock, AIL_vmm_lock_range
Related Basic Types: U32, void, void *
Related FAQs: How careful do I have to be when shutting down?


AIL_mem_free_lock

The function AIL_mem_free_lock frees a pointer previously allocated with AIL_mem_alloc_lock or AIL_file_read.

void AIL_mem_free_lock(
  void const * ptr
);

In Parameters

ptr
specifies the pointer that you want to free.

Discussion

You must use this function to free all pointers allocated with AIL_mem_alloc_lock or AIL_file_read or your application may leak memory.

Under DOS and MacOS 9, this function must not be invoked from an interrupt-based callback function.

Example files that use this function: DEMO.C

Group: Memory and File Services
Related Functions: AIL_MIDI_to_XMI, AIL_compress_ADPCM, AIL_compress_ASI, AIL_compress_DLS, AIL_decompress_ADPCM, AIL_decompress_ASI, AIL_extract_DLS, AIL_file_fss_read, AIL_file_read, AIL_filter_DLS_with_XMI, AIL_find_DLS, AIL_list_DLS, AIL_list_MIDI, AIL_mem_alloc_lock, AIL_mem_use_free, AIL_merge_DLS_with_XMI, AIL_vmm_unlock, AIL_vmm_unlock_range
Related Basic Types: void, void const *
Related FAQs: When can I free the memory I gave to MSS?


AIL_file_read

The function AIL_file_read loads a data file into the specified memory address, optionally allocating the memory as well.

void * AIL_file_read(
  char const * filename,
  void *dest
);

In Parameters

filename
specifies the data file that you'd like to read.

Out Parameters

dest
specifies the address of where you'd like the data loaded. If you pass in NULL for this parameter, then MSS will allocate the memory to hold the data file with AIL_mem_alloc_lock. You can also pass in the flag "FILE_READ_WITH_SIZE" for the dest parameter. This flag also tells MSS to allocate the memory to hold the data file, but, in addition, it will place the size of the data in the first four bytes of the buffer. This saves an extra call to the AIL_file_size function.

Returns

If *dest was NULL, then this function will return the pointer to the new memory block. If *dest was an address, then this function will just return *dest. If an error occurred, then this function will return NULL - use AIL_file_error and AIL_last_error to get the specific error.

Discussion

If you use this function to allocate the memory for you, then you must free the pointer it returns with AIL_mem_free_lock or your application will leak.

Under DOS and MacOS 9, this function must not be invoked from an interrupt-based callback function.

Example files that use this function: DEMO.C

Group: Memory and File Services
Related Functions: AIL_file_error, AIL_file_fss_read, AIL_file_size, AIL_file_write, AIL_last_error, AIL_mem_alloc_lock, AIL_mem_free_lock, AIL_set_file_async_callbacks, AIL_set_file_callbacks
Related Basic Types: char const *, void, void *
Related FAQs: How careful do I have to be when shutting down?, How do I play a digital sound?, How do I play an XMIDI file with a DLS instrument set?, How do I play an XMIDI or MIDI file?


AIL_file_fss_read

The function AIL_file_fss_read loads a data file spec into the specified memory address, optionally allocating the memory as well.

void * AIL_file_fss_read(
  FSSpec const * filename,
  void *dest
);

In Parameters

filename
specifies the data file spec that you'd like to read.

Out Parameters

dest
specifies the address of where you'd like the data loaded. If you pass in NULL for this parameter, then MSS will allocate the memory to hold the data file with AIL_mem_alloc_lock. You can also pass in the flag "FILE_READ_WITH_SIZE" for the dest parameter. This flag also tells MSS to allocate the memory to hold the data file, but, in addition, it will place the size of the data in the first four bytes of the buffer. This saves an extra call to the AIL_file_size function.

Returns

If *dest was NULL, then this function will return the pointer to the new memory block. If *dest was an address, then this function will just return *dest. If an error occurred, then this function will return NULL - use AIL_file_error and AIL_last_error to get the specific error.

Discussion

This function is only used on the Mac with the Classic or Carbon CFM libraries - the Mach-O version of Miles just uses normal Unix style slash separated string filenames.

If you use this function to allocate the memory for you, then you must free the pointer it returns with AIL_mem_free_lock or your application will leak.

This function must not be invoked from an interrupt-based callback function.

Group: Memory and File Services
Related Sections: Filenames on MacOS
Related Functions: AIL_WAV_file_fss_write, AIL_WAV_file_write, AIL_file_error, AIL_file_fss_attrib_write, AIL_file_fss_size, AIL_file_fss_write, AIL_file_read, AIL_file_size, AIL_last_error, AIL_mem_alloc_lock, AIL_mem_free_lock, AIL_set_file_callbacks
Related Basic Types: FSSpec, void, void *


AIL_file_write

The function AIL_file_write creates a new data file and fills it with the specified data.

S32 AIL_file_write(
  char const * filename,
  void const * buf,
  U32 len
);

In Parameters

filename
specifies the data file that you wish to write to.
buf
specifies the address to write from.
len
specifies the number of bytes to write.

Returns

Whether the function succeeded or not.

Discussion

Under DOS and MacOS 9, this function must not be invoked from an interrupt-based callback function.

Group: Memory and File Services
Related Functions: AIL_WAV_file_write, AIL_file_error, AIL_file_read
Related Basic Types: S32, U32, char const *, void const *


AIL_file_fss_write

The function AIL_file_fss_write creates a new MacOS data file spec and fills it with the specified data.

S32 AIL_file_fss_write(
  FSSpec const * filename,
  void const * buf,
  U32 len
);

In Parameters

filename
specifies the data file spec that you wish to write to.
buf
specifies the address to write from.
len
specifies the number of bytes to write.

Returns

Whether the function succeeded or not.

Discussion

This function is only used on the Mac with the Classic or Carbon CFM libraries - the Mach-O version of Miles just uses normal Unix style slash separated string filenames. This function must not be invoked from an interrupt-based callback function.

Group: Memory and File Services
Related Sections: Filenames on MacOS
Related Functions: AIL_WAV_file_fss_write, AIL_WAV_file_write, AIL_file_fss_attrib_write, AIL_file_fss_read
Related Basic Types: FSSpec, S32, U32, void const *


AIL_file_fss_attrib_write

The function AIL_file_fss_attrib_write creates a new MacOS data file spec and fills it with the specified data.

S32 AIL_file_fss_attrib_write(
  FSSpec const * filename,
  void const * buf,
  U32 len,
  U32 in_type,
  U32 in_creator
);

In Parameters

filename
specifies the data file spec that you wish to write to.
buf
specifies the address to write from.
len
specifies the number of bytes to write.
in_type
specifies the MacOS file type of the file to write.
in_creator
specifies the MacOS file creator of the file to write.

Returns

Whether the function succeeded or not.

Discussion

This function is only used on the Mac with the Classic or Carbon CFM libraries - the Mach-O version of Miles just uses normal Unix style slash separated string filenames. This function must not be invoked from an interrupt-based callback function.

Group: Memory and File Services
Related Sections: Filenames on MacOS
Related Functions: AIL_WAV_file_fss_write, AIL_WAV_file_write, AIL_file_fss_read, AIL_file_fss_write
Related Basic Types: FSSpec, S32, U32, void const *


AIL_WAV_file_write

The function AIL_WAV_file_write creates a new Microsoft .WAV file.

S32 AIL_WAV_file_write(
  char const * filename,
  void const * buf,
  U32 len,
  S32 rate,
  S32 format
);

In Parameters

filename
specifies the data file that you wish to write to.
buf
specifies the address to write from.
len
specifies the number of bytes to write.
rate
specifies the playback frequency of the data.
format
specifies the playback format of the data. It should be set to one of the MILES_DIGITAL_FORMAT constants.

Returns

Whether the function succeeded or not.

Discussion

Under DOS and MacOS 9, this function must not be invoked from an interrupt-based callback function.

Group: Memory and File Services
Related Functions: AIL_WAV_file_fss_write, AIL_file_error, AIL_file_fss_attrib_write, AIL_file_fss_read, AIL_file_fss_write, AIL_file_write, AIL_process_digital_audio
Related Basic Types: MILES_DIGITAL_FORMAT, S32, U32, char const *, void const *


AIL_WAV_file_fss_write

The function AIL_WAV_file_fss_write creates a new MacOS .WAV file spec.

S32 AIL_WAV_file_fss_write(
  FSSpec const * filename,
  void const * buf,
  U32 len,
  S32 rate,
  S32 format
);

In Parameters

filename
specifies the data file that you wish to write to.
buf
specifies the address to write from.
len
specifies the number of bytes to write.
rate
specifies the playback frequency of the data.
format
specifies the playback format of the data. It should be set to one of the MILES_DIGITAL_FORMAT constants.

Returns

Whether the function succeeded or not.

Discussion

This function is only used on the Mac with the Classic or Carbon CFM libraries - the Mach-O version of Miles just uses normal Unix style slash separated string filenames. This function must not be invoked from an interrupt-based callback function.

Group: Memory and File Services
Related Sections: Filenames on MacOS
Related Functions: AIL_WAV_file_write, AIL_file_fss_attrib_write, AIL_file_fss_read, AIL_file_fss_write
Related Basic Types: FSSpec, MILES_DIGITAL_FORMAT, S32, U32, void const *


AIL_file_size

The function AIL_file_size returns the size of the specified data file.

S32 AIL_file_size(
  char const * filename
);

In Parameters

filename
specifies the name of the data file to query.

Returns

The size of the file, or -1 if there was an error.

Discussion

Under DOS and MacOS 9, this function must not be invoked from an interrupt-based callback function.

Example files that use this function: DEMO.C

Group: Memory and File Services
Related Functions: AIL_file_error, AIL_file_fss_read, AIL_file_fss_size, AIL_file_read, AIL_set_file_async_callbacks, AIL_set_file_callbacks
Related Basic Types: S32, char const *


AIL_file_fss_size

The function AIL_file_fss_size returns the size of the specified MacOS data file spec.

S32 AIL_file_fss_size(
  FSSpec const * filename
);

In Parameters

filename
specifies the name of the data file spec to query.

Returns

The size of the file, or -1 if there was an error.

Discussion

This function is only used on the Mac with the Classic or Carbon CFM libraries - the Mach-O version of Miles just uses normal Unix style slash separated string filenames. This function must not be invoked from an interrupt-based callback function.

Group: Memory and File Services
Related Sections: Filenames on MacOS
Related Functions: AIL_file_fss_read, AIL_file_size
Related Basic Types: FSSpec, S32


AIL_file_error

The function AIL_file_error returns the last file I/O error from AIL_file_read, AIL_file_write, or AIL_file_size.

S32 AIL_file_error();

Returns

One of the MILES_FILE_ERRORS constants.

Group: Memory and File Services
Related Functions: AIL_WAV_file_write, AIL_file_fss_read, AIL_file_read, AIL_file_size, AIL_file_write
Related Basic Types: MILES_FILE_ERRORS, S32


MILES_FILE_ERRORS

The basic type MILES_FILE_ERRORS describes an error encountered by one of the Miles file I/O functions.

Fundamental Values

Value | Description
AIL_NO_ERROR | No file errors have occurred. (Debugger value: 0).
AIL_IO_ERROR | An unspecified I/O error has occurred. (Debugger value: 1).
AIL_OUT_OF_MEMORY | Couldn't allocate enough memory. (Debugger value: 2).
AIL_FILE_NOT_FOUND | The file you tried to read could not be found. (Debugger value: 3).
AIL_CANT_WRITE_FILE | Error reading from file. (Debugger value: 4).
AIL_CANT_READ_FILE | Error writing to file. (Debugger value: 5).
AIL_DISK_FULL | The drive you are writing to is full. (Debugger value: 6).

Group: Memory and File Services
Related Functions: AIL_file_error


AIL_mem_use_malloc

The function AIL_mem_use_malloc replaces the default memory allocation routines.

void * AIL_mem_use_malloc(
  AILMALLOCCB malloccb
);

In Parameters

malloccb
specifies a memory-allocation routine function of the AILMALLOCCB type.

Returns

The previous malloc routine's address.

Discussion

The memory returned by the allocator routine must be aligned on a 16-byte boundary!

Use this function with AIL_mem_use_free.

Use this routine and AIL_mem_use_free to hook into your own memory management system.

AIL_mem_use_malloc and AIL_mem_use_free should be called prior to AIL_startup.

Group: Memory and File Services
Related Sections: Memory management under DOS, Memory management under MacOS, Memory management under Nintendo Wii, Memory management under PlayStation 2, Memory management under PlayStation 3, Memory management under Win32, Memory management under Win64, Memory management under Xbox, Memory management under Xbox 360
Related Functions: AILMALLOCCB, AIL_mem_alloc_lock, AIL_mem_use_free, AIL_mem_use_malloc, AIL_startup
Related Basic Types: void, void *


AIL_mem_use_free

The function AIL_mem_use_free replaces the default memory freeing routine.

void * AIL_mem_use_free(
  AILFREECB freecb
);

In Parameters

freecb
specifies a memory free routine function of the AILFREECB type.

Returns

The previous free routine's address.

Discussion

Use this function with AIL_mem_use_malloc.

Use this routine and AIL_mem_use_malloc to hook into your own memory management system.

AIL_mem_use_malloc and AIL_mem_use_free should be called prior to AIL_startup.

Group: Memory and File Services
Related Sections: Memory management under DOS, Memory management under MacOS, Memory management under Nintendo Wii, Memory management under PlayStation 2, Memory management under PlayStation 3, Memory management under Win32, Memory management under Win64, Memory management under Xbox, Memory management under Xbox 360
Related Functions: AILFREECB, AIL_mem_free_lock, AIL_mem_use_free, AIL_mem_use_malloc, AIL_startup
Related Basic Types: void, void *


AILMALLOCCB

The function AILMALLOCCB specifies a pointer to a user-defined memory allocation callback.

void * AILCALLBACK AILMALLOCCB(
  U32 bytes
);

In Parameters

bytes
indicates the number of bytes to allocate.

Returns

Returns the newly allocated pointer.

Discussion

The memory returned by this routine must be aligned on a 16-byte boundary!

Group: Memory and File Services
Related Functions: AILFREECB, AIL_mem_use_malloc
Related Basic Types: U32, void, void *


AILFREECB

The function AILFREECB specifies a pointer to a user-defined memory release callback.

void AILCALLBACK AILFREECB(
  void const * ptr
);

In Parameters

ptr
indicates the pointer to free.

Discussion

Always set this callback at the same time that you set the allocation callback.

Group: Memory and File Services
Related Functions: AILMALLOCCB, AIL_mem_use_free
Related Basic Types: void, void const *


AIL_set_file_callbacks

The function AIL_set_file_callbacks replaces the synchronous (blocking) file I/O functions that Miles uses for AIL_file_read, AIL_file_size, and the high-level streaming functions.

void AIL_set_file_callbacks(
  AIL_file_open_callback opencb,
  AIL_file_close_callback closecb,
  AIL_file_seek_callback seekcb,
  AIL_file_read_callback readcb
);

In Parameters

opencb
specifies the callback function to be called when opening a file.
closecb
specifies the callback function to be called when closing a file.
seekcb
specifies the callback function to be called when seeking in a file.
readcb
specifies the callback function to be called when reading from a file.

Discussion

Under Win32, Win64, Xbox, Xbox 360 and PS3, the Miles streaming API can call these routines from a background thread. So, your I/O routines must be thread-safe if you use the high-level streaming API.

Miles uses asynchronous reads on MacOS 9, Wii and PS2 by default. If you call AIL_set_file_callbacks on either of these platforms, Miles will fall back to synchronous I/O, potentially degrading performance. On these platforms, you should normally use AIL_set_file_async_callbacks rather than AIL_set_file_callbacks.

Most applications should allow Miles to perform its own file access. Allowing Miles to maintain its own (possibly-redundant) handles to your audio data files imposes very little system overhead, and eliminates many potential bugs. Note that you do not need to provide file callbacks simply to stream from a packed file; see the AIL_open_stream function for details on how to pass existing file handles and offsets to Miles.

Group: Memory and File Services
Related Functions: AIL_file_close_callback, AIL_file_fss_read, AIL_file_open_callback, AIL_file_read, AIL_file_read_callback, AIL_file_seek_callback, AIL_file_size, AIL_open_stream, AIL_set_file_async_callbacks, AIL_set_file_callbacks
Related Basic Types: void
Related FAQs: How do I access files from a big packed file?


AIL_set_file_async_callbacks

The function AIL_set_file_async_callbacks replaces the file I/O handlers that Miles uses for its high-level streaming functions on certain platforms.

void AIL_set_file_async_callbacks(
  AIL_file_open_callback opencb,
  AIL_file_close_callback closecb,
  AIL_file_seek_callback seekcb,
  AIL_file_async_read_callback areadcb,
  AIL_file_async_status_callback statuscb
);

In Parameters

opencb
specifies the callback function to be called when opening a file.
closecb
specifies the callback function to be called when closing a file.
seekcb
specifies the callback function to be called when seeking in a file.
areadcb
specifies the callback function to be called to initiate an asynchronous read from a file.
statuscb
specifies the callback function to be called when polling the status of an asynchronous file operation.

Discussion

Asynchronous file I/O is used by Miles's high-level streaming subsystem on the Wii, PS2, and MacOS 9 platforms. Most applications should permit Miles to do its own file management, but for those that cannot, this function may be called to provide an alternative set of asynchronous file I/O routines to Miles. These functions must be thread-safe.

Note that permitting Miles to maintain its own (potentially-redundant) handles to your audio data files imposes very little system overhead, and eliminates many potential bugs. You do not need to provide file callbacks simply to stream from a packed file; see the AIL_open_stream function for details on how to pass existing file handles and offsets to Miles.

Group: Memory and File Services
Related Functions: AIL_file_async_read_callback, AIL_file_async_status_callback, AIL_file_close_callback, AIL_file_open_callback, AIL_file_read, AIL_file_seek_callback, AIL_file_size, AIL_open_stream, AIL_set_file_callbacks
Related Basic Types: void
Related FAQs: How do I access files from a big packed file?


AIL_file_open_callback

The function AIL_file_open_callback specifies a user-replaceable callback handler to open a file in MSS.

U32 AILCALLBACK AIL_file_open_callback(
  char const * filename,
  UINTa *file_handle
);

In Parameters

filename
specifies the filename to open.

Out Parameters

file_handle
returns the new file handle, if the open succeeds.

Returns

Returns non-zero, if the open succeeded. Zero, otherwise.

Group: Memory and File Services
Related Functions: AIL_file_async_read_callback, AIL_file_async_status_callback, AIL_file_close_callback, AIL_file_read_callback, AIL_file_seek_callback, AIL_set_file_async_callbacks, AIL_set_file_callbacks
Related Basic Types: U32, UINTa, char const *


AIL_file_close_callback

The function AIL_file_close_callback specifies a user-replaceable callback handler to close a file.

void AILCALLBACK AIL_file_close_callback(
  UINTa file_handle
);

In Parameters

file_handle
specifies the file handle to close.

Group: Memory and File Services
Related Functions: AIL_file_async_read_callback, AIL_file_async_status_callback, AIL_file_open_callback, AIL_file_read_callback, AIL_file_seek_callback, AIL_set_file_async_callbacks, AIL_set_file_callbacks
Related Basic Types: UINTa, void


AIL_file_seek_callback

The function AIL_file_seek_callback specifies a user-replaceable callback handler to seek in a file.

S32 AILCALLBACK AIL_file_seek_callback(
  UINTa file_handle,
  S32 offset,
  U32 type
);

In Parameters

file_handle
specifies the file handle to seek within.
offset
specifies the offset to seek to.
type
will be set to a MILES_FILE_SEEK_TYPE constant.

Returns

This function should return the new absolute position of the file pointer (relative to the beginning of the file).

Group: Memory and File Services
Related Functions: AIL_file_async_read_callback, AIL_file_async_status_callback, AIL_file_close_callback, AIL_file_open_callback, AIL_file_read_callback, AIL_set_file_async_callbacks, AIL_set_file_callbacks
Related Basic Types: MILES_FILE_SEEK_TYPE, S32, U32, UINTa


MILES_FILE_SEEK_TYPE

The basic type MILES_FILE_SEEK_TYPE describes the type of seek to perform.

Fundamental Values

Value | Description
AIL_FILE_SEEK_BEGIN | Seek relative to the beginning of the file.
AIL_FILE_SEEK_CURRENT | Seek relative to the current position of the file.
AIL_FILE_SEEK_END | Seek relative to the end of the file.

Group: Memory and File Services
Related Functions: AIL_file_seek_callback


AIL_file_read_callback

The function AIL_file_read_callback specifies a user-replaceable callback handler to read from a file.

U32 AILCALLBACK AIL_file_read_callback(
  UINTa file_handle,
  void *buffer,
  U32 bytes
);

In Parameters

file_handle
specifies the file handle to read from.
bytes
specifies the number of bytes to read.

Out Parameters

buffer
specifies the address to read into.

Returns

This function should return the total number of bytes actually read (usually "bytes" unless a file I/O error or the end of file was encountered).

Group: Memory and File Services
Related Functions: AIL_file_close_callback, AIL_file_open_callback, AIL_file_seek_callback, AIL_set_file_callbacks
Related Basic Types: U32, UINTa, void


AIL_file_async_read_callback

The function AIL_file_async_read_callback specifies a user-replaceable callback handler to initiate asynchronous reads from a file.

void * AILCALLBACK AIL_file_async_read_callback(
  UINTa file_handle,
  void *buffer,
  U32 bytes
);

In Parameters

file_handle
specifies the file handle to read from.
bytes
specifies the number of bytes to read.

Out Parameters

buffer
specifies the address to read into.

Returns

This function simply initiates an asynchronous read operation. It should return a structure that can be interpreted by the AIL_file_async_status_callback function to poll for completion and file-access errors. The composition of this structure can be application-specific, since it will not be accessed by Miles. Asynchronous reads are used on Wii, PS2 and Macintosh by default.

Group: Memory and File Services
Related Functions: AIL_file_async_status_callback, AIL_file_close_callback, AIL_file_open_callback, AIL_file_seek_callback, AIL_set_file_async_callbacks
Related Basic Types: U32, UINTa, void, void *


AIL_file_async_status_callback

The function AIL_file_async_status_callback specifies a user-replaceable callback handler to poll for completion of an asynchronous read.

S32 AILCALLBACK AIL_file_async_status_callback(
  void * async,
  S32 wait,
  U32 *bytes_read
);

In Parameters

async
specifies a pointer to the user structure allocated by the AIL_file_async_read_callback handler.
wait
will be nonzero if the caller expects the function to wait until the asynchronous read is complete.

Out Parameters

bytes_read
specifies an address to which the number of bytes read so far should be stored.

Returns

After updating *bytes_read, this function should return 1 if the asynchronous read operation is complete, or 0 if it is still in progress. If an error condition is detected, 0 should be stored in *bytes_read and 1 should be returned. Asynchronous reads are used on Wii, PS2 and Macintosh by default.

Group: Memory and File Services
Related Functions: AIL_file_async_read_callback, AIL_file_async_status_callback, AIL_file_close_callback, AIL_file_open_callback, AIL_file_seek_callback, AIL_set_file_async_callbacks
Related Basic Types: S32, U32, void *


AIL_vmm_lock

The function AIL_vmm_lock locks the specified memory range under DOS.

S32 AIL_vmm_lock(
  void const * start,
  U32 size
);

In Parameters

start
specifies the beginning memory address to lock.
size
specifies the size in bytes to lock.

Returns

Whether the function succeeded or not.

Discussion

This function is DOS-only.

You must lock all code and data that will be accessed at callback time.

You must lock all memory accessed at callback time. If your application runs fine under normal DOS, but fails under a DOS window in Windows, then you probably have forgotten to lock all of your memory.

This function must not be invoked from an interrupt-based callback function.

Group: Memory and File Services
Related Sections: Memory management under DOS
Related Functions: AIL_mem_alloc_lock, AIL_vmm_lock_range, AIL_vmm_unlock
Related Basic Types: S32, U32, void const *


AIL_vmm_unlock

The function AIL_vmm_unlock unlocks a piece of memory previously locked with AIL_vmm_lock.

S32 AIL_vmm_unlock(
  void const * start,
  S32 size
);

In Parameters

start
specifies the beginning memory address to unlock.
size
specifies the size in bytes to unlock.

Returns

Whether the function succeeded or not.

Discussion

This function is DOS-only.

You must unlock all memory that you lock with AIL_vmm_lock.

This function must not be invoked from an interrupt-based callback function.

Group: Memory and File Services
Related Functions: AIL_mem_free_lock, AIL_vmm_lock, AIL_vmm_unlock_range
Related Basic Types: S32, void const *


AIL_vmm_lock_range

The function AIL_vmm_lock_range locks the specified memory range under DOS.

S32 AIL_vmm_lock_range(
  void const * ptr1,
  void const * ptr2
);

In Parameters

ptr1
specifies the beginning memory address to lock.
ptr2
specifies the ending memory address to lock.

Returns

Whether the function succeeded or not.

Discussion

This function is DOS-only.

You must lock all code and data that will be accessed at callback time. This includes both code and data addresses.

This function is handy to lock code ranges because you generally don't know how long your procedures are in bytes. So for code ranges, use this function with the address of function that you want to lock for ptr1, and the address of the next function in the source file for ptr2.

Be careful when using empty functions with this call - occasionally optimizing compilers will move empty functions to save code space. The best way to ensure against this is to add a few lines of dummy code in your function.

You must lock all memory accessed at callback time. If your application runs fine under normal DOS, but fails under a DOS window in Windows, then you probably have forgotten to lock all of your memory.

This function must not be invoked from an interrupt-based callback function.

Group: Memory and File Services
Related Functions: AIL_mem_alloc_lock, AIL_vmm_lock, AIL_vmm_unlock_range
Related Basic Types: S32, void const *


AIL_vmm_unlock_range

The function AIL_vmm_unlock_range unlocks a piece of memory previously locked with AIL_vmm_lock_range.

S32 AIL_vmm_unlock_range(
  void const * ptr1,
  void const * ptr2
);

In Parameters

ptr1
specifies the beginning memory address to unlock.
ptr2
specifies the ending memory address to unlock.

Returns

Whether the function succeeded or not.

Discussion

This function is DOS-only.

You must unlock all memory that you lock with AIL_vmm_lock_range.

This function must not be invoked from an interrupt-based callback function.

Group: Memory and File Services
Related Functions: AIL_mem_free_lock, AIL_vmm_lock_range, AIL_vmm_unlock
Related Basic Types: S32, void const *


Timer Services

Discussion

The Timer Services are used to provide cross-platform timer callbacks. Timers are implemented in different technology depending on the Miles platform:

Timer callbacks under Win32 and Win64 are implemented as background threads.

Timer callbacks under MacOS are implemented as MacOS system timers (which are interrupt based under MacOS 9 and thread based under MacOS X).

Timer callbacks under DOS are implemented as hardware interrupts.

Timer Services
AIL_ms_count | returns a millisecond accurate timer count (one thousand ticks per second).
AIL_us_count | returns a microsecond accurate timer count (one million ticks per second).
AIL_register_timer | registers a callback function callback_fn to receive asynchronous time-slice service from a timer, and returns a handle HTIMER which may be used to start, stop, and program the function's assigned timer.
AILTIMERCB | specifies a user-defined timer callback.
AIL_set_timer_user | instructs the MSS timer dispatcher to pass the value user to the timer callback function associated with the timer handle timer.
AIL_set_timer_period | programs a timer for callback service at periods ranging from 1 microsecond to 1,000,000,000 microseconds (approximately 15 minutes).
AIL_set_timer_frequency | programs a timer for callback service at frequencies ranging from 1 Hz (Hertz, or cycles per second) to 1,000,000 Hz.
AIL_set_timer_divisor | programs a timer for callback service at a rate which is given in terms of the constant value that would normally be used to program the IBM PC's 8253 Programmable Interval Timer chip for the desired interrupt rate, if the application were to access the chip directly.
AIL_interrupt_divisor | returns the current value used internally by the Miles Sound System's Timer Services to program the IBM PC's 8253 Programmable Interval Timer chip for periodic INT 8 (IRQ 0) service.
AIL_start_timer | initiates or resumes periodic time-slice interrupt service to the callback function registered to timer.
AIL_stop_timer | stops periodic time-slice interrupt service to the callback function registered to timer.
AIL_release_timer_handle | stops periodic time-slice interrupt service to the callback function registered to timer, and releases the timer's handle.
AIL_get_timer_highest_delay | returns the highest delay in timer servicing under Win 32.
AIL_delay | suspends foreground program execution.
AIL_lock | suspends timer service to all MSS drivers and application callback functions until a matching call to AIL_unlock is made.
AIL_unlock | resumes timer service to all MSS drivers and application callback functions after a matching call to AIL_lock.
AIL_start_all_timers | initiates or resumes periodic time-slice interrupt service to the callback functions registered to all active timer handles.
AIL_stop_all_timers | stops periodic time-slice interrupt service to the callback functions registered to all active timer handles.
AIL_release_all_timers | stops periodic time-slice interrupt service to the callback functions registered to all active timer handles, and releases all active timer handles.


AIL_ms_count

The function AIL_ms_count returns a millisecond accurate timer count (one thousand ticks per second).

U32 AIL_ms_count();

Returns

The current timer count.

Discussion

Use this function if you just need a simple timer count, rather than registering a super-fast timer callback.

This function will always return increasing values.

Under MSS for DOS, this function reads the timer chip directly to obtain millisecond resolution, unless it is running in a Windows or Windows 9x DOS box. In a DOS box, MSS queries Windows directly for the current millisecond count. That means that this function is just as accurate in a Windows DOS box as it is under stand-alone DOS.

Under MSS for Windows, this function uses QueryPerformanceCounter for very accurate timings.

Group: Timer Services
Related Functions: AIL_delay, AIL_us_count
Related Basic Types: U32


AIL_us_count

The function AIL_us_count returns a microsecond accurate timer count (one million ticks per second).

U32 AIL_us_count();

Returns

The current timer count.

Discussion

Since this function moves so quickly, it wraps around every 71 minutes. It is most useful for profiling.

This function will always return increasing values (until it wraps).

Under MSS for DOS, this function reads the timer chip directly to obtain microsecond resolution, unless it is running in a Windows or Windows 9x DOS box. In a DOS box, MSS queries Windows directly for the current microsecond count. That means that this function is just as accurate in a Windows DOS box as it is under stand-alone DOS.

Under MSS for Windows, this function uses QueryPerformanceCounter for very accurate timings.

Group: Timer Services
Related Functions: AIL_delay, AIL_ms_count
Related Basic Types: U32


AIL_register_timer

The function AIL_register_timer registers a callback function callback_fn to receive asynchronous time-slice service from a timer, and returns a handle HTIMER which may be used to start, stop, and program the function's assigned timer.

HTIMER AIL_register_timer(
  AILTIMERCB callback_fn
);

In Parameters

callback_fn
points to a timer callback function declared as the AILTIMERCB type.

Returns

A timer handle which may be used to start, stop, and control the timer.

Discussion

A timer is an API resource which, can provide periodic interrupt service to a given function at any desired frequency within the limits of system overhead. Depending upon the platform, this timer service may be implemented with threads, interrupts or system callbacks.

Since the DOS Miles Sound System must directly program the IBM PC's Programmable Interval Timer hardware, MSS makes this and other timer-related functions externally available in case the application itself requires periodic interrupt service. Up to 16 independent timer callback functions may be registered, but each sound driver which requires periodic service, including all XMIDI and digital audio drivers, will allocate one of the 16 available timer handles for its own use.

AIL_register_timer will return the value -1 if no timer handles are available.

Timer callback service will not begin until the timer's service rate is established with AIL_set_timer_period, AIL_set_timer_frequency, or AIL_set_timer_divisor, and the AIL_start_timer function is called to initiate timer service.

The timer callback function's user argument receives the value passed by the application to the AIL_set_timer_user function. It is required under both DOS and Windows.

The user argument allows a single function to be registered multiple times as a timer client, and called to handle timer processing for several different object instances. For example, an application may cast a structure pointer to type U32 and, by passing it to AIL_set_timer_user, cause the structure pointer to be passed on to that timer handle's timer service routine, which would then operate only on the structure whose pointer is passed to it by the MSS timer dispatcher. This is illustrative of the techniques MSS itself uses to manage multiple XMIDI or digital audio drivers simultaneously, and any application with an "object-oriented" design may benefit as well from the user feature.

Most MSS functions can be safely invoked from within timer callback functions. Exceptions include driver-installation or driver-shutdown functions and any other functions which may perform DOS or BIOS calls, such as AIL_init_sequence. These exceptions are noted in the descriptions of the functions involved. If in doubt about whether a particular action may safely be performed from within a timer callback function, contact RAD Game Tools for assistance.

Group: Timer Services
Related Functions: AILTIMERCB, AIL_init_sequence, AIL_register_timer, AIL_release_timer_handle, AIL_set_timer_divisor, AIL_set_timer_frequency, AIL_set_timer_period, AIL_set_timer_user, AIL_start_timer
Related Basic Types: HTIMER, MILES_PREFERENCES
Related FAQs: What's the deal with callbacks - are they threads, interrupts, system timers, or what?


AILTIMERCB

The function AILTIMERCB specifies a user-defined timer callback.

void AILCALLBACK AILTIMERCB(
  UINTa user
);

In Parameters

user
indicates the user value specified by a call to AIL_set_timer_user.

Discussion

Depending on the OS, timer callbacks can be made from an interrupt, background thread, multimedia callback, or a system timer.

Group: Timer Services
Related Functions: AIL_register_timer, AIL_set_timer_user
Related Basic Types: UINTa, void


AIL_set_timer_user

The function AIL_set_timer_user instructs the MSS timer dispatcher to pass the value user to the timer callback function associated with the timer handle timer.

UINTa AIL_set_timer_user(
  HTIMER timer,
  UINTa user
);

In Parameters

timer
is a handle to the desired timer.
user
specifies the value which is to be passed to timer's callback function.

Returns

The previous timer user value.

Discussion

See AIL_register_timer for details on how a timer callback function may be registered with the MSS API, and any desired timer user value may be passed to it.

Group: Timer Services
Related Functions: AILTIMERCB, AIL_register_timer
Related Basic Types: HTIMER, UINTa


AIL_set_timer_period

The function AIL_set_timer_period programs a timer for callback service at periods ranging from 1 microsecond to 1,000,000,000 microseconds (approximately 15 minutes).

void AIL_set_timer_period(
  HTIMER timer,
  U32 microseconds
);

In Parameters

timer
is a handle to the timer to program.
microseconds
specifies the desired callback interval in microseconds.

Discussion

Any one of three functions may be used to program a timer's callback rate. These functions are AIL_set_timer_period, AIL_set_timer_frequency, and AIL_set_timer_divisor. All three of these functions perform exactly the same task, but accept their values in different units. Period in microseconds, for example, is the reciprocal of frequency in megahertz. For fast timer repetition rates, greater precision may be obtained by expressing the timer period as its reciprocal, frequency, and using AIL_set_timer_frequency instead.

In practice, the fastest possible rate will be substantially slower than the theoretical value due to the host system's interrupt-processing overhead. MSS may exhibit internal stack overflows if any timer is programmed for a rate of more than a thousand or so calls per second. This does not necessarily indicate a fault in either the DOS extender or MSS, but is a sign that the PC hardware in use is incapable of keeping up with the demands of very-high-speed timer service in protected mode.

Under normal circumstances, the programmed timer service rate will exhibit a long-term accuracy of better than ± 100 parts per million (ppm). This accuracy figure may be somewhat degraded under certain environments such as Microsoft Windows.

The fastest possible timer period available under the Windows MSS API is 5 milliseconds (200 Hz) by default. This period limit may be changed to as little as 1 millisecond (1000 Hz) by changing the AIL_MM_PERIOD preference value immediately after calling AIL_startup.

Group: Timer Services
Related Functions: AIL_register_timer, AIL_set_timer_divisor, AIL_set_timer_frequency, AIL_set_timer_period, AIL_startup
Related Basic Types: HTIMER, MILES_PREFERENCES, U32, void


AIL_set_timer_frequency

The function AIL_set_timer_frequency programs a timer for callback service at frequencies ranging from 1 Hz (Hertz, or cycles per second) to 1,000,000 Hz.

void AIL_set_timer_frequency(
  HTIMER timer,
  U32 hertz
);

In Parameters

timer
is a handle to the timer to program.
hertz
specifies the desired callback rate in hertz (callbacks per second).

Discussion

Any one of three functions may be used to program a timer's callback rate. These functions are AIL_set_timer_period, AIL_set_timer_frequency, and AIL_set_timer_divisor. All three of these functions perform exactly the same task, but accept their values in different units. Frequency in megahertz, for example, is the reciprocal of period in microseconds. For slow timer repetition rates, greater precision may be obtained by expressing timer frequencies lower than one hertz (Hz) in reciprocal form, and calling AIL_set_timer_period instead.

In practice, the fastest possible rate will be substantially slower than the theoretical value due to the host system's interrupt-processing overhead. MSS may exhibit internal stack overflows if any timer is programmed for a rate of more than a thousand or so calls per second. This does not necessarily indicate a fault in either the DOS extender or MSS, but is a sign that the PC hardware in use is incapable of keeping up with the demands of very-high-speed timer service in protected mode.

Under normal circumstances, the programmed timer service rate will exhibit a long-term accuracy of better than ± 100 parts per million (ppm). This accuracy figure may be somewhat degraded under certain environments such as Microsoft Windows.

The fastest possible timer period available under the Windows MSS API is 5 milliseconds (200 Hz) by default. This period limit may be changed to as little as 1 millisecond (1000 Hz) by changing the AIL_MM_PERIOD preference value immediately after calling AIL_startup.

Group: Timer Services
Related Functions: AIL_register_timer, AIL_set_timer_divisor, AIL_set_timer_frequency, AIL_set_timer_period, AIL_startup
Related Basic Types: HTIMER, MILES_PREFERENCES, U32, void


AIL_set_timer_divisor

The function AIL_set_timer_divisor programs a timer for callback service at a rate which is given in terms of the constant value that would normally be used to program the IBM PC's 8253 Programmable Interval Timer chip for the desired interrupt rate, if the application were to access the chip directly.

void AIL_set_timer_divisor(
  HTIMER timer,
  U32 PIT_divisor
);

In Parameters

timer
is a handle to the timer to program.
PIT_divisor
is the value which would normally be used to program the PIT chip directly at the desired rate.

Discussion

When this function is used to program a timer, the timer's frequency is given by 1193181 / PIT_divisor Hz.

Any one of three functions may be used to program a timer's callback rate. These functions are AIL_set_timer_period, AIL_set_timer_frequency, and AIL_set_timer_divisor. All three of these functions perform exactly the same task, but accept their values in different units. AIL_set_timer_divisor is useful primarily as an aid in porting applications to MSS which formerly accessed the timer chip directly, or when timer service must be "stolen" from the MSS system for any reason.

In practice, the fastest possible rate will be substantially slower than the theoretical value due to the host system's interrupt-processing overhead. MSS may exhibit internal stack overflows if any timer is programmed for a rate of more than a thousand or so calls per second. This does not necessarily indicate a fault in either the DOS extender or MSS, but is a sign that the PC hardware in use is incapable of keeping up with the demands of very-high-speed timer service in protected mode.

Under normal circumstances, the programmed timer service rate will exhibit a long-term accuracy of better than ± 100 parts per million (ppm). This accuracy figure may be somewhat degraded under certain environments such as Microsoft Windows.

The fastest possible timer period available under the Windows MSS API is 5 milliseconds (200 Hz) by default. This period limit may be changed to as little as 1 millisecond (1000 Hz) by changing the AIL_MM_PERIOD preference value immediately after calling AIL_startup.

Group: Timer Services
Related Functions: AIL_interrupt_divisor, AIL_register_timer, AIL_set_timer_divisor, AIL_set_timer_frequency, AIL_set_timer_period, AIL_startup
Related Basic Types: HTIMER, MILES_PREFERENCES, U32, void


AIL_interrupt_divisor

The function AIL_interrupt_divisor returns the current value used internally by the Miles Sound System's Timer Services to program the IBM PC's 8253 Programmable Interval Timer chip for periodic INT 8 (IRQ 0) service.

U32 AIL_interrupt_divisor();

Returns

The value last used to program the IBM timer hardware for interrupt service by the MSS system.

Discussion

This function is intended for use by applications which must seize direct control of the IBM's timer interrupt hardware. Its use is not recommended under ordinary circumstances.

The MSS Timer Services are fast enough and flexible enough to meet nearly any conceivable application's needs for periodic callback service, and programmers are strongly encouraged to make use of them whenever possible. In the rare event that this is not practical, AIL_interrupt_divisor allows the application to continue to play sound and music while circumventing the MSS's timer interrupt handler for its own purposes. The application must assume responsibility for generating software INT 8 calls at the indicated rate.

This function is not supported under Windows or MacOS.

Group: Timer Services
Related Functions: AIL_interrupt_divisor, AIL_set_timer_divisor
Related Basic Types: U32


AIL_start_timer

The function AIL_start_timer initiates or resumes periodic time-slice interrupt service to the callback function registered to timer.

void AIL_start_timer(
  HTIMER timer
);

In Parameters

timer
is a handle to the timer to start.

Group: Timer Services
Related Functions: AIL_register_timer, AIL_stop_timer
Related Basic Types: HTIMER, void


AIL_stop_timer

The function AIL_stop_timer stops periodic time-slice interrupt service to the callback function registered to timer.

void AIL_stop_timer(
  HTIMER timer
);

In Parameters

timer
is a handle to the timer to stop.

Discussion

The timer's periodic service can be restarted with AIL_start_timer.

It is permissible but not necessary to call AIL_stop_timer immediately prior to releasing the timer handle with AIL_release_timer_handle, or shutting down the MSS API with AIL_shutdown.

Group: Timer Services
Related Functions: AIL_release_timer_handle, AIL_shutdown, AIL_start_timer, AIL_stop_timer
Related Basic Types: HTIMER, void


AIL_release_timer_handle

The function AIL_release_timer_handle stops periodic time-slice interrupt service to the callback function registered to timer, and releases the timer's handle.

void AIL_release_timer_handle(
  HTIMER timer
);

In Parameters

timer
specifies the timer handle to be released.

Discussion

Once a timer's handle has been released, it is made available for future reallocation by AIL_register_timer, and can no longer be used to restart or reprogram the timer.

Group: Timer Services
Related Functions: AIL_register_timer, AIL_shutdown, AIL_stop_timer
Related Basic Types: HTIMER, void


AIL_get_timer_highest_delay

The function AIL_get_timer_highest_delay returns the highest delay in timer servicing under Win 32.

U32 AIL_get_timer_highest_delay();

Returns

The highest delay since the last call to this function.

Discussion

This function is only available under Windows and MacOS. Under Windows 9x, the OS task switcher can cause the Miles timer to slowdown when the system is under load (the NT scheduler is much better - it rarely slows down). The most common side effect of this timer delay is the digital audio subsystem skipping. This function allows you to measure just how good the OS is servicing your timers.

On Win32 and Win64, you can use the DIG_DS_MIX_FRAGMENT_CNT preference to increase the digital subsystem's mix ahead time to smooth over the delay returned by this function.

On MacOS, you can use the DIG_SM_MIX_FRAGMENT_CNT preference to increase the digital subsystem's mix ahead time to smooth over the delay returned by this function.

The Windows and MacOS thread schedulers usually have the most trouble during disk I/O.

Group: Timer Services
Related Sections: Sharing the CPU under MacOS, Sharing the CPU under Win32, Sharing the CPU under Win64
Related Functions: AIL_serve
Related Basic Types: MILES_PREFERENCES, U32
Related FAQs: My sound is skipping on Windows or MacOS X - what can I do?


AIL_delay

The function AIL_delay suspends foreground program execution.

void AIL_delay(
  S32 intervals
);

In Parameters

intervals
specifies the number of 16 millisecond periods to wait.

Discussion

You can also use the AIL_ms_count function for other CPU-independent delays.

This function may be used to provide a CPU-independent delay for operations such as MIDI System Exclusive transmission via the AIL_send_sysex_message function, or other cases where the application needs to suspend processing for a brief amount of time.

This function is designed to emulate the delay of waiting for a vertical retrace without actually doing so. It uses the AIL_ms_count to delay exactly 16 milliseconds for every interval.

Group: Timer Services
Related Functions: AIL_ms_count, AIL_send_sysex_message, AIL_us_count
Related Basic Types: S32, void


AIL_lock

The function AIL_lock suspends timer service to all MSS drivers and application callback functions until a matching call to AIL_unlock is made.

void AIL_lock();

Discussion

Calls to AIL_lock and AIL_unlock should bracket any sections of application code which must not be interrupted by background MSS timer interrupts. Examples would include non-reentrant application functions which may be called from both the foreground application and an MSS timer, XMIDI, or digital sound callback function.

AIL_lock increments a counter which is decremented by each corresponding call to AIL_unlock. When an AIL_unlock call decrements the counter to zero, MSS timer service is resumed.

Under DOS, BIOS system timer service continues while AIL_lock is in effect. The CPU interrupt state is not affected by either AIL_lock or AIL_unlock.

Group: Timer Services
Related Functions: AIL_lock, AIL_unlock
Related Basic Types: void


AIL_unlock

The function AIL_unlock resumes timer service to all MSS drivers and application callback functions after a matching call to AIL_lock.

void AIL_unlock();

Discussion

Calls to AIL_lock and AIL_unlock should bracket any sections of application code which must not be interrupted by background MSS timer interrupts. Examples would include non-reentrant application functions which may be called from both the foreground application and an MSS timer, XMIDI, or digital sound callback function.

AIL_lock increments a counter which is decremented by each corresponding call to AIL_unlock. When an AIL_unlock call decrements the counter to zero, MSS timer service is resumed.

Under DOS, BIOS system timer service continues while AIL_lock is in effect. The CPU interrupt state is not affected by either AIL_lock or AIL_unlock.

Group: Timer Services
Related Functions: AIL_lock, AIL_unlock
Related Basic Types: void


AIL_start_all_timers

The function AIL_start_all_timers initiates or resumes periodic time-slice interrupt service to the callback functions registered to all active timer handles.

void AIL_start_all_timers();

Discussion

The application program should not normally call AIL_start_all_timers, as this function affects timers assigned to sound drivers as well as any timers registered to the application.

Group: Timer Services
Related Functions: AIL_start_all_timers, AIL_stop_all_timers
Related Basic Types: void


AIL_stop_all_timers

The function AIL_stop_all_timers stops periodic time-slice interrupt service to the callback functions registered to all active timer handles.

void AIL_stop_all_timers();

Discussion

The application program should not normally call AIL_stop_all_timers, as this function affects timers assigned to sound drivers as well as any timers assigned to the application. Stopping a timer assigned to a sound driver may result in "stuck notes," looping sound fragments, or other unwanted effects.

Group: Timer Services
Related Functions: AIL_start_all_timers, AIL_stop_all_timers
Related Basic Types: void


AIL_release_all_timers

The function AIL_release_all_timers stops periodic time-slice interrupt service to the callback functions registered to all active timer handles, and releases all active timer handles.

void AIL_release_all_timers();

Discussion

The application program should not normally call AIL_release_all_timers, as this function affects timers assigned to sound drivers as well as any timers assigned to the application. Releasing a timer handle which is assigned to a sound driver may result in "stuck notes," looping sound fragments, or other unwanted effects.

Group: Timer Services
Related Functions: AIL_release_all_timers
Related Basic Types: void


Digital Audio Services

Discussion

The Digital Audio Services are used to play both 2D (non-spatialized) and 3D (attenuated by position and/or directionality) digital audio samples from memory-resident buffers, low-level streaming ("double-buffered") buffers, or high-level streams.

These functions can directly play PCM, IMA ADPCM, or ASI-compressed data such as Ogg Vorbis and MPEG Layer 3 files. On the original Xbox, you can also play Xbox ADPCM data.

See the Digital Audio Streaming Services section for details on streaming an audio sample from a disk file.

Digital Audio Services
AIL_open_digital_driver | opens a digital driver to play 2D digital audio.
MSS_SPEAKER | may be used to specify either a source (HSAMPLE/HSTREAM) channel or an HDIGDRIVER's destination speaker output channel.
MSS_MC_SPEC | specifies an output channel-configuration option for use with AIL_open_digital_driver or AIL_quick_startup.
MILES_OPEN_DIGITAL_FLAGS | specifies open flags for the AIL_open_digital_driver function.
AIL_close_digital_driver | shuts down and closes an audio driver which was opened by a previous call to AIL_open_digital_driver.
AIL_digital_handle_release | temporarily releases the hardware digital handle (either the HWAVEOUT handle, the DirectSound object, or the Sound Manager buffer) back to the system.
AIL_digital_handle_reacquire | attempts to reacquire hardware digital handle (either the HWAVEOUT handle, the DirectSound object, or the Sound Manager buffer) from the system.
AIL_set_DirectSound_HWND | assigns the HWND to use for DirectSound's focus control.
AIL_HWND | returns the HWND that MSS has detected as your primary HWND.
AIL_set_digital_master_volume_level | establishes an overall `master volume` value which is used to scale the volumes of all subsequent digital audio samples.
AIL_digital_master_volume_level | returns the current digital master volume setting in use.
AIL_set_digital_master_reverb | sets the global reverb settings to use.
MILES_ROOM_TYPE | specifies a room type to use for the environmental reverb.
AIL_digital_master_reverb | retrieves the global reverb settings to use.
AIL_set_digital_master_reverb_levels | establishes the overall `master reverb` levels which are used to scale the levels of the reverb of all subsequent digital audio samples.
AIL_digital_master_reverb_levels | retrieves the overall `master reverb` levels.
AIL_set_speaker_reverb_levels | sets the global wet and dry reverb-response scalars at one or more speakers.
AIL_speaker_reverb_levels | returns three arrays describing the wet and dry reverb-response scalars at all speakers, plus the speaker channel identifiers themselves.
AIL_calculate_3D_channel_levels | gives your application direct access to the Miles 3D sound-positioner function.
MSSVECTOR3D
AIL_allocate_sample_handle | searches for a free sample handle and returns it to the application for use in the playback of digital audio data.
AIL_release_sample_handle | releases a sample handle previously allocated with AIL_allocate_sample_handle.
AIL_init_sample | prepares a sample handle for playback of audio data.
AIL_set_sample_address | specifies the starting address and length for a raw data sample.
AIL_set_sample_file | initializes a sample's address, length, type, and flags to prepare for playback of memory-resident sound data.
AIL_set_named_sample_file | initializes a sample's address, length, type, and flags to prepare for playback of a memory-resident sound data.
AIL_set_sample_info | initializes a sample's address, length, type, and flags to prepare for playback of memory-resident sound data.
MILES_DIGITAL_FORMAT | describes the type of digital audio.
MILES_DIGITAL_FLAGS | describes the layout of digital audio.
AIL_start_sample | starts playback of a sample from its beginning.
AIL_stop_sample | stops playback of a sample.
AIL_resume_sample | resumes playback of a sample which was previously stopped.
AIL_end_sample | terminates playback of a sample, setting its status to SMP_DONE.
AIL_set_sample_playback_rate | sets a sample's playback rate in hertz.
AIL_sample_playback_rate | returns the current sample playback rate.
AIL_set_sample_volume_pan | controls a sample's playback volume level and pan.
AIL_sample_volume_pan | returns the current sample volume and pan, from 0 to 1.0.
AIL_set_sample_reverb_levels | changes the reverb levels of a digital audio sample.
AIL_sample_reverb_levels | retrieves the reverb levels of a digital audio sample.
AIL_set_sample_low_pass_cut_off | applies a low-pass filter to the digital audio sample.
AIL_sample_low_pass_cut_off | retrieves the current low-pass cutoff setting.
AIL_set_sample_51_volume_pan | controls a sample's playback volume and pan values when using multichannel discrete output modes.
AIL_sample_51_volume_pan | returns the current sample 5.1 volumes and pan, from 0 to 1.0, resulting from a prior call to AIL_set_sample_51_volume_pan or AIL_set_sample_51_volume_levels.
AIL_set_sample_volume_levels | controls a sample's playback volume levels.
AIL_sample_volume_levels | returns the current sample volumes, from 0 to 1.0.
AIL_set_sample_channel_levels | scales the output contribution from each source channel in the specified HSAMPLE to each speaker.
AIL_sample_channel_levels | returns an array of level-scaling factors for one or more combinations of source channels and destination speakers.
AIL_sample_output_levels | returns the final mixer level-scaling factors for one or more combinations of source channels and destination speakers.
AIL_set_sample_51_volume_levels | controls a sample's playback volume levels when using multichannel discrete output modes.
AIL_sample_51_volume_levels | returns the current sample 5.1 volumes, from 0 to 1.0, on discrete multichannel platforms.
AIL_set_sample_3D_distances | sets the minimum and maximum distances for a given sample handle.
AIL_sample_3D_distances | returns the current minimum and maximum distances for the specified sample handle.
AIL_set_sample_3D_cone | sets the sound emission cone on a sample.
AIL_sample_3D_cone | retrieves the current sound emission cone of a sample.
AIL_set_sample_occlusion | sets the occlusion for the specified 3D sample.
AIL_sample_occlusion | retrieves the current occlusion level of the given sample.
AIL_set_sample_obstruction | sets the obstruction for the specified 3D sample.
AIL_sample_obstruction | retrieves the current obstruction level of the given sample.
AIL_set_sample_exclusion | sets the exclusion for the specified 3D sample.
AIL_sample_exclusion | retrieves the current exclusion level of the given sample.
AIL_set_listener_3D_position | sets the three-dimensional position of the 3D listener.
AIL_listener_3D_position | retrieves the current 3D position of the 3D listener.
AIL_set_listener_3D_velocity | sets the current velocity of the 3D listener.
AIL_listener_3D_velocity | retrieves the current velocity of the 3D listener.
AIL_set_listener_3D_velocity_vector | sets the current velocity of the 3D listener.
AIL_update_listener_3D_position | updates the 3D listener's position based on its previously set velocity and the specified delta time in milliseconds.
AIL_set_listener_3D_orientation | specifies the orientation of the 3D listener.
AIL_listener_3D_orientation | retrieves the orientation of the 3D listener.
AIL_set_sample_3D_position | sets a sample's current position in 3D space.
AIL_sample_3D_position | retrieves the current 3D position of a 3D sample.
AIL_set_sample_3D_velocity | sets the current velocity of a 3D sample.
AIL_sample_3D_velocity | retrieves the current velocity of a 3D sample.
AIL_set_sample_3D_velocity_vector | sets the current velocity of a 3D sample.
AIL_update_sample_3D_position | updates a 3D sample's position based on its previously-set velocity and the specified delta time in milliseconds.
AIL_set_sample_3D_orientation | specifies the orientation of a 3D sample.
AIL_sample_3D_orientation | retrieves the orientation of a 3D sample.
AIL_set_room_type | sets the room type that the listener is currently in.
AIL_room_type | returns the current room type.
AIL_set_3D_rolloff_factor | sets the driver's global 3D rolloff factor.
AIL_3D_rolloff_factor | returns the driver's current 3D rolloff factor.
AIL_set_3D_doppler_factor | sets the driver's global 3D Doppler factor.
AIL_3D_doppler_factor | returns the driver's current 3D Doppler factor.
AIL_set_3D_distance_factor | sets the driver's global 3D distance factor.
AIL_3D_distance_factor | returns the driver's current 3D distance factor.
AIL_set_sample_loop_count | arranges for a sample to be restarted immediately upon completion, for a total of two or more iterations.
AIL_sample_loop_count | returns the number of loop iterations remaining for the given sample.
AIL_set_sample_loop_block | arranges for a sub-block of a sample to be looped.
AIL_sample_loop_block | returns the beginning and ending loop offsets previously passed to AIL_set_sample_loop_block.
AIL_set_sample_position | adjusts the playback position of a sample.
AIL_sample_position | reports the current playback position of a sample.
AIL_set_sample_ms_position | adjusts the playback position of a sample.
AIL_sample_ms_position | reports the current playback position and length of a sample in milliseconds.
AIL_sample_status | returns the status of a given sample handle.
MILES_DIGITAL_STATUS | describes the current state of the digital audio.
AIL_set_sample_user_data | sets a value for one of eight user data entries associated with each sample handle.
AIL_sample_user_data | retrieves a value for one of eight user data entries associated with each sample handle.
AIL_minimum_sample_buffer_size | returns the minimum usable buffer size for use with the low-level streaming function AIL_load_sample_buffer.
AIL_sample_buffer_available | checks to see if any of the buffers associated with a sample handle are ready to be filled with new audio data by the AIL_load_sample_buffer function.
AIL_load_sample_buffer | sets the address and length for one of the low-level streaming buffers associated with a sample handle, enabling low-level streaming mode for that sample handle.
AIL_sample_buffer_info | returns detailed information about the status of the low-level streaming buffers for the specified sound handle.
AIL_sample_buffer_count | returns the number of low-level streaming buffers associated with a sample.
AIL_set_sample_buffer_count | sets the number of low-level streaming buffers available for use with a given sample handle.
AIL_sample_channel_count | returns information about the source channels associated with a sample.
AIL_sample_granularity | returns the granularity of a sample in bytes.
AIL_set_sample_adpcm_block_size | sets the block size for the IMA ADPCM data.
AIL_digital_CPU_percent | returns the percentage of total CPU being spent in the Miles digital processing loop.
AIL_digital_latency | returns the approximate latency of a sound if it were started immediately.
AIL_set_speaker_configuration | establishes the listener-relative location of the speaker array, and the falloff power factor used for sample spatialization.
AIL_speaker_configuration | returns an array of 3D vectors describing the listener-relative locations of the array of speakers associated with the current output format, plus some additional information about the format.
AIL_enumerate_output_filter_driver_properties | enumerates the possible driver-level properties of an output filter.
AIL_enumerate_output_filter_sample_properties | enumerates the possible sample-level properties of an output filter.
AIL_output_filter_driver_property | retrieves and/or sets driver-level properties for an output filter.
AIL_register_SOB_callback | arranges for callback service to be provided to an application's function just before a block of sample data is merged into the hardware buffer.
AILSAMPLECB | specifies a user-defined digital audio callback.
AIL_register_EOB_callback | arranges for callback service to be provided to an application function immediately upon reaching the end of a sample buffer.
AIL_register_EOS_callback | arranges for callback service to be provided to an application function immediately upon reaching the end of a sample.
AILFALLOFFCB | specifies a user-defined 3D distance-based falloff function callback.
AIL_register_falloff_function_callback | allows an application to override the system's default distance-based attenuation calculations for 3D-enabled samples.
AIL_active_sample_count | returns the number of currently-playing samples.
AIL_digital_configuration | returns information about the specified digital driver.
AIL_get_DirectSound_info | returns the pointers to the DirectSound object currently being used by MSS.
AIL_install_DIG_INI | installs and initializes the currently selected MSS .DIG driver file under DOS.
MILES_INSTALL_STATUS | specifies possible results from loading a DOS driver.
AIL_install_DIG_driver_file | installs and initializes an MSS-compatible .DIG driver file under DOS.
IO_PARMS | indicates specific hardware settings to use when installing a digital driver


AIL_open_digital_driver

The function AIL_open_digital_driver opens a digital driver to play 2D digital audio.

HDIGDRIVER AIL_open_digital_driver(
  U32 frequency,
  S32 bits,
  S32 channels,
  U32 flags
);

In Parameters

frequency
specifies the output sample frequency to initialize the driver to.
bits
specifies the bits of sound quality to initialize the driver to. Use 8 for 8-bit, and 16 for 16-bit.
channels
specifies the number of sound channels. You will usually default to using MSS_MC_USE_SYSTEM_CONFIG, but you can also use 1 for mono, 2 for stereo, or one of the MSS_MC_SPEC specifiers.
flags
0 or one of the MILES_OPEN_DIGITAL_FLAGS constants.

Returns

If successful, this function returns a non-zero handle to a digital driver. If the driver failed to open, then 0 is returned (use AIL_last_error for the cause).

Discussion

This function will open a digital driver on any of the Miles platforms.

Important: the channels parameter does not specify the number of available mixer voices! The number of mixer voices is determined by the value of the DIG_MIXER_CHANNELS preference at the time this function is called.

When using the MSS_MC_USE_SYSTEM_CONFIG flag for the channels parameter, the output configuration is determined as follows (note that not all of the speaker systems are supported on all platforms):

Operating System Reports | Equivalent MSS_MC_SPEC Value
Headphones | MSS_MC_HEADPHONES
Mono speaker | MSS_MC_MONO
Quad speakers | MSS_MC_40_DISCRETE
Stereo speakers | MSS_MC_STEREO
Surround speakers | MSS_MC_SRS_CIRCLE_SURROUND
5.1 speakers | MSS_MC_51_DISCRETE
6.1 speakers | MSS_MC_61_DISCRETE
5.1 speakers | MSS_MC_51_DISCRETE
8.1 speakers | MSS_MC_81_DISCRETE

You can query the chosen MSS_MC_SPEC value by calling AIL_speaker_configuration on the returned HDIGDRIVER. Unfortunately, the control-panel or other system setting may not reflect the user's actual hardware configuration. Worst, from the sound driver's point of view, the configuration may be determined by a separate, proprietary applet -- which may or may not keep itself synchronized with the operating system settings. Further, the limited range of operating system values don't begin to address all of the possible configurations (for example, under Windows there is no option for 6.1 speakers). Therefore, it's best not to rely solely on the OS to report a meaningful speaker-configuration value; we strongly recommend offering the user the ability to select an MSS_MC_ configuration directly as part of your application's sound-options dialog. So, default to MSS_MS_USE_SYSTEM_CONFIG, but give the user the ability to override.

Also on Win32 and Win64, make sure that you have created an HWND before calling this function (DirectSound requires this).

Note that under Win32 and Win64, MSS will try DirectSound first, and then fall back to waveOut if DirectSound failed to open or was using emulation mode. If you want to force DirectSound or waveOut specifically, use the AIL_OPEN_DIGITAL_FORCE_PREFERENCE flag.

On Win32 and Win64, you can use the two preferences, DIG_PREFERRED_WO_DEVICE and DIG_PREFERRED_DS_DEVICE, to force AIL_open_digital_driver and AIL_quick_startup to use a specific waveOut device ID or DirectSound LPGUID. This allows you to enumerate and open a specific sound card (or even multiple sound cards) if necessary.

Under the original Xbox, this function will open the DirectSound system.

The Xbox hardware always uses a fixed 48 Khz, 16-bit output, so the frequency, bits, and channels don't specify the output mode, but instead specify the default format of each sound buffer. You should set these parameters to those of the majority of your sound samples (if not, Miles will simply reset the format when you start the sound which is a little less efficient).

Under the Xbox 360, this function will open the XAudio system.

On the Nintendo Wii, the driver is always opened in 32038 Hz 16-bit mode.

On the Sony PS2, the driver is always opened in 48 kHz 16-bit stereo mode. The only meaningful configurations are MSS_MC_STEREO, MSS_MC_40_DTS, and MSS_MC_51_DTS.

On the Sony PS3, the driver is always opened in 48 kHz, 32-bit floating point. The only meaningful configurations are MSS_MC_STEREO, MSS_MC_51_DISCRETE, and MSS_MC_71_DISCRETE.

Under MacOS, MSS will use the Sound Manager. There have been many versions of the Sound Manager, some of which behave better than others. If you have trouble, try downloading the latest version of QuickTime - this will get you the latest version of Sound Manager.

Under DOS, MSS will set the sound format preferences and then call AIL_install_DIG_INI to load a real-mode DOS driver.

For an understanding of the options available with the output_channels parameter, see the How do I use multi-channel sound output in Miles? FAQ.

Example files that use this function: EXAMMS.CPP

Group: Digital Audio Services
Related Sections: Miles DTS Provider for the Sony PS2, Miles Dolby Surround Provider, Miles SRS Circle Surround Provider
Related Functions: AIL_HWND, AIL_close_digital_driver, AIL_digital_output_filter, AIL_get_DirectSound_info, AIL_install_DIG_INI, AIL_install_DIG_driver_file, AIL_last_error, AIL_open_digital_driver, AIL_output_filter_driver_property, AIL_quick_handles, AIL_quick_startup, AIL_set_DirectSound_HWND, AIL_set_sample_playback_rate, AIL_set_sample_volume_pan, AIL_speaker_configuration
Related Basic Types: HDIGDRIVER, MILES_OPEN_DIGITAL_FLAGS, MILES_PREFERENCES, MSS_MC_SPEC, MSS_PLATFORM_PROPERTY, S32, U32
Related FAQs: How do I initialize the Miles Sound System for use?, How do I use multi-channel sound output in Miles?, I'm setting a preference and it isn't having any effect - what's going on?, My 3D audio is a lot louder than my 2D audio - what can I do?, My application is crashing - what should I try?, What's the best way to port my older Miles application to MSS 7?


MSS_SPEAKER

The basic type MSS_SPEAKER may be used to specify either a source (HSAMPLE/HSTREAM) channel or an HDIGDRIVER's destination speaker output channel.

Fundamental Values

Value | Description
MSS_SPEAKER_FRONT_LEFT | Equal to the constant 0.
MSS_SPEAKER_FRONT_RIGHT | Equal to the constant 1.
MSS_SPEAKER_FRONT_CENTER | Equal to the constant 2.
MSS_SPEAKER_LOW_FREQUENCY | Equal to the constant 3.
MSS_SPEAKER_BACK_LEFT | Equal to the constant 4.
MSS_SPEAKER_BACK_RIGHT | Equal to the constant 5.
MSS_SPEAKER_FRONT_LEFT_OF_CENTER | Equal to the constant 6.
MSS_SPEAKER_FRONT_RIGHT_OF_CENTER | Equal to the constant 7.
MSS_SPEAKER_BACK_CENTER | Equal to the constant 8.
MSS_SPEAKER_SIDE_LEFT | Equal to the constant 9.
MSS_SPEAKER_SIDE_RIGHT | Equal to the constant 10.
MSS_SPEAKER_TOP_CENTER | Equal to the constant 11.
MSS_SPEAKER_TOP_FRONT_LEFT | Equal to the constant 12.
MSS_SPEAKER_TOP_FRONT_CENTER | Equal to the constant 13.
MSS_SPEAKER_TOP_FRONT_RIGHT | Equal to the constant 14.
MSS_SPEAKER_TOP_BACK_LEFT | Equal to the constant 15.
MSS_SPEAKER_TOP_BACK_CENTER | Equal to the constant 16.
MSS_SPEAKER_TOP_BACK_RIGHT | Equal to the constant 17.

Discussion

See the How do I use multi-channel sound output in Miles? FAQ for more information on the MSS_SPEAKER type.

Group: Digital Audio Services
Related Functions: AIL_calculate_3D_channel_levels
Related Basic Types: MSS_SPEAKER
Related FAQs: How do I use multi-channel sound output in Miles?


MSS_MC_SPEC

The basic type MSS_MC_SPEC specifies an output channel-configuration option for use with AIL_open_digital_driver or AIL_quick_startup.

Fundamental Values

Value | Description
MSS_MC_MONO | Conventional monaural (single-speaker) sound. Equal to the constant 1.
MSS_MC_STEREO | Conventional stereo sound. Equal to the constant 2. Miles's 3D positional math assumes two (left and right) speakers are in front of the listener at 45-degree angles.
MSS_MC_HEADPHONES | Similar to MSS_MC_STEREO, but Miles assumes the speakers are positioned directly to either side of the listener.
MSS_MC_DOLBY_SURROUND | This option assumes the user has connected a Dolby Surround-capable receiver to their (two-channel) sound card. It is identical to the Miles Dolby Surround M3D provider from earlier versions. Dolby Surround provides three logical channels (front left, front right, and monaural rear).
MSS_MC_SRS_CIRCLE_SURROUND | SRS Circle Surround(r) is a two-channel matrix format can be thought of as an improved replacement for Dolby Surround. It is compatible with consumer receivers that support Dolby, and offers 6.1 logical channels (front left, front right, front center, subwoofer, rear left, rear right, and rear center) on native Circle Surround(r)-compatible equipment.
MSS_MC_40_DISCRETE | This option assumes that four speakers (front left, front right, rear left, and rear right) are connected in a quadraphonic discrete configuration without the center speaker or subwoofer typical of 5.1 configurations.
MSS_MC_51_DISCRETE | Use this option to support the 'sweet spot' of current home audio systems, the 5.1-channel discrete configuration.
MSS_MC_40_DTS | Four-channel discrete DTS support via the S/PDIF port on the Sony PS2.
MSS_MC_51_DTS | True 5.1-channel discrete DTS support via the S/PDIF port on the Sony PS2.
MSS_MC_61_DISCRETE | Similar to 5.1, but with a rear center speaker.
MSS_MC_71_DISCRETE | Similar to 5.1, but with side surrounds.
MSS_MC_81_DISCRETE | Similar to 5.1, but with both side surrounds and a center rear speaker.
MSS_MC_DIRECTSOUND3D | Uses DirectSound3D for output, bypassing the Miles internal mixer.
MSS_MC_EAX2 | Adds hardware-accelerated environmental reverb effects, occlusion, obstruction, and per-sample wet/dry mix control to DirectSound3D.
MSS_MC_EAX3 | Adds exclusion and several other properties to the EAX 2 feature set.
MSS_MC_EAX4 | Higher-quality effects and new control options (see the EAX4EXAM.CPP example application), currently available only in Creative Labs' highest-end hardware.
MSS_MC_USE_SYSTEM_CONFIG | This option causes MSS to choose an appropriate MSS_MC_SPEC setting based on the Windows control-panel settings as reported by IDirectSound::GetSpeakerConfig.

Discussion

See the How do I use multi-channel sound output in Miles? FAQ for more information on the MSS_MC_SPEC type, including a list of currently-supported values.

Group: Digital Audio Services
Related Sections: Miles DTS Provider for the Sony PS2
Related Functions: AIL_digital_master_reverb, AIL_digital_master_reverb_levels, AIL_open_digital_driver, AIL_quick_set_reverb_levels, AIL_quick_startup, AIL_sample_channel_levels, AIL_sample_output_levels, AIL_set_digital_master_reverb, AIL_set_digital_master_reverb_levels, AIL_set_room_type, AIL_set_sample_channel_levels, AIL_set_sample_volume_pan, AIL_set_speaker_configuration, AIL_set_speaker_reverb_levels, AIL_speaker_configuration, AIL_speaker_reverb_levels
Related Basic Types: MSS_MC_SPEC
Related FAQs: How do I use multi-channel sound output in Miles?, My application is crashing - what should I try?, What's the best way to port my older Miles application to MSS 7?


MILES_OPEN_DIGITAL_FLAGS

The basic type MILES_OPEN_DIGITAL_FLAGS specifies open flags for the AIL_open_digital_driver function.

Fundamental Values

Value | Description
0 | Under Win32 and Win64, the default flag of zero tells Miles to try DirectSound first, and then try waveOut if DirectSound fails (or is using emulation mode). Under MacOS, the default flag simply opens Sound Manager. Under DOS, the default flag simply opens the DOS driver specified in the DIG.INI file.
AIL_OPEN_DIGITAL_FORCE_PREFERENCE | Under Win32 and Win64, this flag tells AIL_open_digital_driver to obey the DIG_USE_WAVEOUT preference instead of trying DirectSound first and then waveOut automatically. Under DOS, this causes the sound format parameters to AIL_open_digital_driver to be ignored and the DIG_HARDWARE_SAMPLE_RATE, DIG_USE_STEREO, and DIG_USE_16_BITS preferences are used to setup the driver.
AIL_OPEN_DIGITAL_NEED_HW_3D | On original Xbox, this flag says to open the digital driver with hardware 3D support. Functions such as AIL_set_sample_3D_position and AIL_set_sample_3D_distances will be hardware-accelerated for better performance, but stereo samples and streams are not supported. Voice availability is also limited to a maximum of 64.
AIL_OPEN_DIGITAL_NEED_FULL_3D | On original Xbox, this optional flag is added to the other flags to force the use of the larger HRTF filter tables. The full HRTF tables are about 60K larger.
AIL_OPEN_DIGITAL_NEED_LIGHT_3D | On original Xbox, this optional flag is added to the other flags to force the use of the smaller HRTF filter tables. The light HRTF tables are about 60K smaller.
AIL_OPEN_DIGITAL_NEED_HW_REVERB | On original Xbox, this optional flag is added to the other flags to specify that you require I3DL2 reverb in your application. Hardware reverb may be enabled even if you don't use AIL_OPEN_DIGITAL_NEED_HW_3D. Miles doesn't support software reverb on the Xbox, so if you want environmental reverb effects, this flag is mandatory. Note that even though the reverb algorithm is implemented in DSP hardware, there is a slight cost in memory usage and latency associated with turning it on.
AIL_OPEN_DIGITAL_USE_IOP_CORE0 | On PS2, this optional flag specifies that MSS should send its output to IOP core 0, rather than the default IOP core 1 destination. Most applications will not need to use this flag. (When a DTS 4.0 or DTS 5.1 configuration is opened, core 0 is selected automatically, and this flag has no effect.) Be sure to review the discussion of the RAD_IOP layer in the PS2 support-services section before using this flag.

Group: Digital Audio Services
Related Functions: AIL_open_digital_driver, AIL_set_sample_3D_distances, AIL_set_sample_3D_position
Related Basic Types: MILES_PREFERENCES


AIL_close_digital_driver

The function AIL_close_digital_driver shuts down and closes an audio driver which was opened by a previous call to AIL_open_digital_driver.

void AIL_close_digital_driver(
  HDIGDRIVER dig
);

In Parameters

dig
indicates the driver to shut down and unload from memory.

Discussion

It is not necessary to call this function immediately prior to application termination, as AIL_shutdown can be used to shut down and close all loaded drivers.

Under DOS and MacOS 9, this function must not be invoked from an interrupt-based callback function.

Group: Digital Audio Services
Related Functions: AIL_install_DIG_INI, AIL_install_DIG_driver_file, AIL_open_digital_driver, AIL_shutdown, AIL_uninstall_driver
Related Basic Types: HDIGDRIVER, void
Related FAQs: What's the best way to port my older Miles application to MSS 7?


AIL_digital_handle_release

The function AIL_digital_handle_release temporarily releases the hardware digital handle (either the HWAVEOUT handle, the DirectSound object, or the Sound Manager buffer) back to the system.

S32 AIL_digital_handle_release(
  HDIGDRIVER dig
);

In Parameters

dig
indicates the driver to release to the system.

Returns

Non-zero on success. Zero if the dig parameter is null or invalid, or if a per-voice output filter (e.g., DirectSound3D or EAX) is in use.

Discussion

On Windows, this function is usually used with the AIL_digital_handle_release function in the WM_ACTIVATEAPP message processing code to allow other applications to play digital sound.

On MacOS, other applications can always still play audio - that is, Sound Manager can still be used by other applications when Miles is using it.

This function will automatically pause any samples that are currently playing. These samples will then be automatically restarted when AIL_digital_handle_reacquire is called.

This function is also a convenient way to play Video for Windows AVI files inside an MSS application.

Under MacOS 9, this function must not be invoked from an interrupt-based callback function.

This function is not supported under the MS-DOS, Xbox, Wii, Sony PS2 or Sony PS3 versions of MSS.

Under Windows, this function will fail, returning zero, if a per-voice hardware provider such as a DirectSound3D or EAX output filter is in use. Because the system can't guarantee that we'll be able to reassign hardware voices to all active HSAMPLEs, supporting automatic release/reacquire capability isn't practical when we're not doing the mixing ourselves. In general, we strongly recommend that your application maintain its own 'shadow' state for its playing HSAMPLEs. Use MSS to render your application's audio state -- not to store it. The examms.cpp demo program offers a useful illustration of this technique. It can shut down and reopen its HDIGDRIVER, restoring its complete playback state from application-owned structures without using AIL_digital_handle_release or AIL_digital_handle_reacquire at all.

Group: Digital Audio Services
Related Functions: AIL_digital_handle_reacquire, AIL_digital_handle_release, AIL_open_input
Related Basic Types: HDIGDRIVER, MILES_DIGITAL_STATUS, S32


AIL_digital_handle_reacquire

The function AIL_digital_handle_reacquire attempts to reacquire hardware digital handle (either the HWAVEOUT handle, the DirectSound object, or the Sound Manager buffer) from the system.

S32 AIL_digital_handle_reacquire(
  HDIGDRIVER dig
);

In Parameters

dig
indicates the driver to try to reacquire.

Returns

Non-zero on success. Zero if the digital handle was still in use by the system, or if a voice output filter (e.g., DirectSound3D or EAX) is in use.

Discussion

On Windows, this function is usually used with the AIL_digital_handle_release function in the WM_ACTIVATEAPP message processing code to allow other applications to play digital sound.

On MacOS, other applications can always still play audio - that is, Sound Manager can still be used by other applications when Miles is using it.

This function will automatically restart any samples that were playing when AIL_digital_handle_release was called.

Important! Note that this function can fail if the digital handle is still in use, and that there is a slight delay from when a digital handle is freed to when that handle becomes available again. So, if you place this call in your WM_ACTIVATEAPP message handling code, you will have to retry the reacquire periodically if the call fails.

Under MacOS 9, this function must not be invoked from an interrupt-based callback function.

This function is not supported under the MS-DOS, Xbox, Wii, Sony PS2 or Sony PS3 versions of MSS.

Under Windows, this function will fail, returning zero, if a per-voice hardware provider such as a DirectSound3D or EAX output filter is in use. Because the system can't guarantee that we'll be able to reassign hardware voices to all active HSAMPLEs, supporting automatic release/reacquire capability isn't practical when we're not doing the mixing ourselves. In general, we strongly recommend that your application maintain its own 'shadow' state for its playing HSAMPLEs. Use MSS to render your application's audio state -- not to store it. The examms.cpp demo program offers a useful illustration of this technique. It can shut down and reopen its HDIGDRIVER, restoring its complete playback state from application-owned structures without using AIL_digital_handle_release or AIL_digital_handle_reacquire at all.

Group: Digital Audio Services
Related Functions: AIL_digital_handle_reacquire, AIL_digital_handle_release, AIL_open_input
Related Basic Types: HDIGDRIVER, S32


AIL_set_DirectSound_HWND

The function AIL_set_DirectSound_HWND assigns the HWND to use for DirectSound's focus control.

S32 AIL_set_DirectSound_HWND(
  HDIGDRIVER dig,
  HWND wnd
);

In Parameters

dig
indicates the driver to set the DirectSound HWND for.
wnd
indicates the HWND to use with DirectSound.

Discussion

This call is only necessary if Miles guesses wrong when it tries to figure out what your application's main HWND is.

You can call AIL_HWND to retrieve the HWND that is currently being used.

This function is only used under Windows.

Group: Digital Audio Services
Related Functions: AIL_HWND, AIL_open_digital_driver
Related Basic Types: HDIGDRIVER, HWND, S32


AIL_HWND

The function AIL_HWND returns the HWND that MSS has detected as your primary HWND.

HWND AIL_HWND();

Discussion

You can change the HWND with by calling AIL_set_DirectSound_HWND before AIL_open_digital_driver.

Group: Digital Audio Services
Related Functions: AIL_open_digital_driver, AIL_set_DirectSound_HWND
Related Basic Types: HWND


AIL_set_digital_master_volume_level

The function AIL_set_digital_master_volume_level establishes an overall "master volume" value which is used to scale the volumes of all subsequent digital audio samples.

void AIL_set_digital_master_volume_level(
  HDIGDRIVER dig,
  F32 master_volume
);

In Parameters

dig
indicates the driver for which the new master volume setting is to be specified.
master_volume
specifies a linear volume scaling level (0-1.0, with 0 corresponding to complete silence, 0.5 corresponding to a 6-dB reduction in volume, and 1.0 corresponding to zero attenuation).

Discussion

This function controls an attenuation factor which is applied to all digital samples in software. Like other MSS level-control functions, it has no effect on any hardware mixer settings.

By default, the digital master volume value is initialized to 1.0 (no attenuation).

Group: Digital Audio Services
Related Functions: AIL_digital_master_volume_level, AIL_sample_volume_pan, AIL_set_sample_volume_pan
Related Basic Types: F32, HDIGDRIVER, void


AIL_digital_master_volume_level

The function AIL_digital_master_volume_level returns the current digital master volume setting in use.

F32 AIL_digital_master_volume_level(
  HDIGDRIVER dig
);

In Parameters

dig
indicates the driver for which the master volume setting is to be determined.

Returns

The current digital master volume setting (0-1.0, with 0 corresponding to complete silence and 1.0 corresponding to zero attenuation).

Discussion

By default, the digital master volume value is initialized to 1.0 (no attenuation).

Group: Digital Audio Services
Related Functions: AIL_sample_volume_pan, AIL_set_digital_master_volume_level, AIL_set_sample_volume_pan
Related Basic Types: F32, HDIGDRIVER


AIL_set_digital_master_reverb

The function AIL_set_digital_master_reverb sets the global reverb settings to use.

void AIL_set_digital_master_reverb(
  HDIGDRIVER dig,
  F32 reverb_time,
  F32 reverb_predelay,
  F32 reverb_damping
);

In Parameters

dig
indicates the driver for which the new master reverb settings are to be specified.
reverb_time
specifies the total reverb time from 0.0 to 8.0 seconds.
reverb_predelay
specifies the delay before the reverb will be heard from 0.0 to 0.250 seconds.
reverb_damping
specifies the high frequency damping that should be performed - this is a low-pass filter performed on the samples that are fed to the reverb engine. Specified from 0.0 to 1.0 relative to playback frequency of the sample.

Discussion

The AIL_set_room_type function uses this function to set EAX-compatible room styles.

You need to set a non-zero wet reverb level of any samples that you want to apply global reverb to - use the AIL_set_sample_reverb_levels to do this.

Global reverb is very inexpensive to apply (about 0.25% - one forth of one percent - per sample).

This function is not supported on Xbox, as the hardware reverb system is much more sophisticated and should be programmed directly. See the Xbox docs for details.

This function will have no effect with per-voice hardware drivers that don't support reverb in hardware. Currently, this applies only to the MSS_MC_DIRECTSOUND3D value from the MSS_MC_SPEC list, since the EAX providers handle reverb directly and the software-mixing options emulate EAX.

Group: Digital Audio Services
Related Sections: EAX Compatible Reverb
Related Functions: AIL_digital_master_reverb_levels, AIL_quick_set_reverb_levels, AIL_set_room_type, AIL_set_sample_reverb_levels
Related Basic Types: F32, HDIGDRIVER, MSS_MC_SPEC, void
Related FAQs: How do I set an environmental reverb room style?


MILES_ROOM_TYPE

The basic type MILES_ROOM_TYPE specifies a room type to use for the environmental reverb.

Fundamental Values

Value | Description
ENVIRONMENT_GENERIC | Default setting. (Debugger value: 0).
ENVIRONMENT_PADDEDCELL | Padded cell reverb. (Debugger value: 1).
ENVIRONMENT_ROOM | Simple room reverb. (Debugger value: 2).
ENVIRONMENT_BATHROOM | Bathroom reverb. (Debugger value: 3).
ENVIRONMENT_LIVINGROOM | Living room reverb. (Debugger value: 4).
ENVIRONMENT_STONEROOM | Stone room reverb. (Debugger value: 5).
ENVIRONMENT_AUDITORIUM | Auditorium reverb. (Debugger value: 6).
ENVIRONMENT_CONCERTHALL | Concert hall reverb. (Debugger value: 7).
ENVIRONMENT_CAVE | Cave reverb. (Debugger value: 8).
ENVIRONMENT_ARENA | Arena reverb. (Debugger value: 9).
ENVIRONMENT_HANGAR | Hanger reverb. (Debugger value: 10).
ENVIRONMENT_CARPETEDHALLWAY | Carpeted hallway reverb. (Debugger value: 11).
ENVIRONMENT_HALLWAY | Hallway reverb. (Debugger value: 12).
ENVIRONMENT_STONECORRIDOR | Stone corridor reverb. (Debugger value: 13).
ENVIRONMENT_ALLEY | Alley reverb. (Debugger value: 14).
ENVIRONMENT_FOREST | Forest reverb. (Debugger value: 15).
ENVIRONMENT_CITY | City reverb. (Debugger value: 16).
ENVIRONMENT_MOUNTAINS | Mountains reverb. (Debugger value: 17).
ENVIRONMENT_QUARRY | Quarry reverb. (Debugger value: 18).
ENVIRONMENT_PLAIN | Open plain reverb. (Debugger value: 19).
ENVIRONMENT_PARKINGLOT | Parking lot reverb. (Debugger value: 20).
ENVIRONMENT_SEWERPIPE | Sewer pipe reverb. (Debugger value: 21).
ENVIRONMENT_UNDERWATER | Underwater reverb. (Debugger value: 22).
ENVIRONMENT_DRUGGED | Drugged reverb. (Debugger value: 23).
ENVIRONMENT_DIZZY | Dizzy reverb. (Debugger value: 24).
ENVIRONMENT_PSYCHOTIC | Psychotic reverb. (Debugger value: 25).

Group: Digital Audio Services
Related Sections: Creative's EAX 2 Properties
Related Functions: AIL_room_type, AIL_set_room_type
Related Structures: EAX_REVERB


AIL_digital_master_reverb

The function AIL_digital_master_reverb retrieves the global reverb settings to use.

void AIL_digital_master_reverb(
  HDIGDRIVER dig,
  F32 *reverb_time,
  F32 *reverb_predelay,
  F32 *reverb_damping
);

In Parameters

dig
indicates the driver to query.

Out Parameters

reverb_time
retrieves the total reverb time in seconds.
reverb_predelay
retrieves the delay before the reverb will be heard in seconds.
reverb_damping
retrieves the high frequency damping.

Discussion

The AIL_set_room_type function uses these values to set EAX compatible room styles.

This function is not supported on Xbox, as the hardware reverb system is much more sophisticated and should be programmed directly. See the Xbox docs for details.

This function will have no effect with per-voice hardware drivers that don't support reverb in hardware. Currently, this applies only to the MSS_MC_DIRECTSOUND3D value from the MSS_MC_SPEC list, since the EAX providers handle reverb directly and the software-mixing options emulate EAX.

Group: Digital Audio Services
Related Functions: AIL_digital_master_reverb_levels, AIL_set_room_type
Related Basic Types: F32, HDIGDRIVER, MSS_MC_SPEC, void


AIL_set_digital_master_reverb_levels

The function AIL_set_digital_master_reverb_levels establishes the overall "master reverb" levels which are used to scale the levels of the reverb of all subsequent digital audio samples.

void AIL_set_digital_master_reverb_levels(
  HDIGDRIVER dig,
  F32 dry_level,
  F32 wet_level
);

In Parameters

dig
indicates the driver for which the new reverb level is to be specified.
dry_level
specifies a scaling factor for the dry sound signal (the non-reverbed sound). The range is 0.0 for no output, 1.0 for full output.
wet_level
specifies a scaling factor for the wet sound signal (the reverberations). The range is 0.0 for no output, 1.0 for full output.

Discussion

This function controls a driver-wide scaling factor which is applied to all digital samples in software.

These levels are linear scalars, where each doubling of the level value represents a 6-dB change in the wet or dry level. For instance, a wet_level or dry_level value of 0.5 is 6 dB quieter than a value of 1.0, and 0.25 would be 12 dB quieter than 1.0.

By default, both the wet and dry scaling factors are set to 1.0.

The AIL_set_room_type function sets the master reverb levels to emulate EAX compatible room settings.

This function will have no effect with per-voice hardware drivers that don't support reverb in hardware. Currently, this applies only to the MSS_MC_DIRECTSOUND3D value from the MSS_MC_SPEC list, since the EAX providers handle reverb directly and the software-mixing options emulate EAX.

Group: Digital Audio Services
Related Functions: AIL_digital_master_reverb_levels, AIL_sample_reverb_levels, AIL_set_room_type, AIL_set_sample_reverb_levels
Related Basic Types: F32, HDIGDRIVER, MSS_MC_SPEC, void
Related FAQs: How do I set an environmental reverb room style?, What's the best way to port my older Miles application to MSS 7?


AIL_digital_master_reverb_levels

The function AIL_digital_master_reverb_levels retrieves the overall "master reverb" levels.

void AIL_digital_master_reverb_levels(
  HDIGDRIVER dig,
  F32 *dry_level,
  F32 *wet_level
);

In Parameters

dig
indicates the driver to query.

Out Parameters

dry_level
retrieves the scaling factor for the dry sound signal (the non-reverbed sound). The range is 0.0 for no output, 1.0 for full output.
wet_level
retrieves the scaling factor for the dry sound signal (the reverbed sound). The range is 0.0 for no output, 1.0 for full output.

Discussion

By default, both the wet and dry scaling factors are set to 1.0.

The AIL_set_room_type function sets the master reverb levels to emulate EAX compatible room settings.

This function will have no effect with per-voice hardware drivers that don't support reverb in hardware. Currently, this applies only to the MSS_MC_DIRECTSOUND3D value from the MSS_MC_SPEC list, since the EAX providers handle reverb directly and the software-mixing options emulate EAX.

Group: Digital Audio Services
Related Functions: AIL_digital_master_reverb, AIL_sample_reverb_levels, AIL_set_digital_master_reverb, AIL_set_digital_master_reverb_levels, AIL_set_room_type, AIL_set_sample_reverb_levels
Related Basic Types: F32, HDIGDRIVER, MSS_MC_SPEC, void


AIL_set_speaker_reverb_levels

The function AIL_set_speaker_reverb_levels sets the global wet and dry reverb-response scalars at one or more speakers.

void AIL_set_speaker_reverb_levels(
  HDIGDRIVER dig,
  F32 * wet_array,
  F32 * dry_array,
  MSS_SPEAKER * speaker_index_array,
  S32 n_levels
);

In Parameters

dig
indicates the driver whose speaker reverb response should be set.
wet_array
if not NULL, specifies an array of coefficients from 0.0 to 1.0 which will scale the wet reverb response at each specified output channel, from 0.0 (no wet reverb) to 1.0 (full wet reverb response).
dry_array
if not NULL, specifies an array of coefficients from 0.0 to 1.0 which will scale the dry response at each specified output channel, from 0.0 (no dry level) to 1.0 (full dry level response).
speaker_index_array
specifies an array of speaker locations for each supplied wet_array/dry_array entry.
n_levels
specifies the number of entries in wet_array, dry_array, and speaker_index_array.

Discussion

When the Miles software mixer is in use, this function may be called to suppress or amplify wet/dry reverb effects on a per-speaker basis. For instance, you could use it to keep reverb out of the surround channels in a 5.1 configuration. By default, all speaker response scalars are set to 1.0 when the driver is opened.

The wet_array and dry_array values are linear scalars, where each doubling of the level value represents a 6-dB change in the wet or dry level for that channel. For instance, a value of 0.5 is 6 dB quieter than a value of 1.0, and 0.25 would be 12 dB quieter than 1.0.

Either the wet_array or dry_array parameters may be set to NULL to leave the corresponding driver-level response scalars intact.

This function will have no effect with per-voice hardware drivers that don't use the Miles software mixer. Currently, this applies only to the MSS_MC_DIRECTSOUND3D and MSS_MC_EAX? values from the MSS_MC_SPEC list.

This function is also not supported on Xbox 1, as the hardware reverb system is much more sophisticated and should be programmed directly. See the Xbox docs for details.

For a detailed understanding of channel-based control functions such as this one, you should carefully review the How do I use multi-channel sound output in Miles? FAQ.

Group: Digital Audio Services
Related Functions: AIL_speaker_reverb_levels
Related Basic Types: F32, HDIGDRIVER, MSS_MC_SPEC, MSS_SPEAKER, S32, void
Related FAQs: How do I use multi-channel sound output in Miles?


AIL_speaker_reverb_levels

The function AIL_speaker_reverb_levels returns three arrays describing the wet and dry reverb-response scalars at all speakers, plus the speaker channel identifiers themselves.

S32 AIL_speaker_reverb_levels(
  HDIGDRIVER dig,
  F32 * *wet_array,
  F32 * *dry_array,
  MSS_SPEAKER * *speaker_index_array
);

In Parameters

dig
indicates the driver whose speaker reverb response should be queried.

Out Parameters

wet_array
if not NULL, receives a pointer to an array of coefficients from 0.0 to 1.0 which scale the wet reverb response at each supported output channel, from 0.0 (no wet reverb) to 1.0 (full wet reverb response).
dry_array
if not NULL, receives a pointer to an array of coefficients from 0.0 to 1.0 which scale the dry response at each supported output channel, from 0.0 (no dry level) to 1.0 (full dry level response).
speaker_index_array
if not NULL, receives a pointer to the array of speaker locations supported by the HDIGDRIVER.

Returns

The number of entries in the returned arrays.

Discussion

When the Miles software mixer is in use, the AIL_set_speaker_reverb_levels function may be called to suppress or amplify reverb effects on a per-speaker basis. For instance, you could use it to keep reverb out of the surround channels in a 5.1 configuration. By default, all speaker reverb response scalars are set to 1.0 when the driver is opened.

This function will not return meaningful information with per-voice hardware drivers that don't use the Miles software mixer. Currently, this applies only to the MSS_MC_DIRECTSOUND3D and MSS_MC_EAX? values from the MSS_MC_SPEC list.

This function is also not supported on Xbox 1, as the hardware reverb system is much more sophisticated and should be programmed directly. See the Xbox docs for details.

For a detailed understanding of channel-based control functions such as this one, you should carefully review the How do I use multi-channel sound output in Miles? FAQ.

Group: Digital Audio Services
Related Functions: AIL_set_speaker_reverb_levels
Related Basic Types: F32, HDIGDRIVER, MSS_MC_SPEC, MSS_SPEAKER, S32
Related FAQs: How do I use multi-channel sound output in Miles?


AIL_calculate_3D_channel_levels

The function AIL_calculate_3D_channel_levels gives your application direct access to the Miles 3D sound-positioner function.

S32 AIL_calculate_3D_channel_levels(
  HDIGDRIVER dig,
  F32 *channel_levels,
  MSS_SPEAKER * *speaker_array,
  MSSVECTOR3D const *src_pos,
  MSSVECTOR3D const *src_face,
  MSSVECTOR3D const *src_up,
  F32 src_inner_angle,
  F32 src_outer_angle,
  F32 src_outer_volume,
  F32 src_max_dist,
  F32 src_min_dist,
  MSSVECTOR3D const *listen_pos,
  MSSVECTOR3D const *listen_face,
  MSSVECTOR3D const *listen_up,
  F32 rolloff_factor,
  MSSVECTOR3D const *doppler_velocity,
  F32 *doppler_shift
);

In Parameters

dig
specifies the digital audio driver from which to acquire the listener-relative speaker location and falloff-power parameters.
src_pos
specifies the effective 3D position of an audio emitter (source) object.
src_face
specifies the source object's facing direction (front vector).
src_up
specifies the source object's up vector.
src_inner_angle
is the inner angle of the source's sound cone in degrees (0 to 360). If the listener is within this angle of this sample, then the sound is at its normal volume (based on its volume, distance, occlusion, etc). The src_inner_angle value should always be smaller than, or equal to, src_outer_angle. A value of 360.0 disables cone attenuation entirely.
src_outer_angle
is the outer angle of the source's sound cone in degrees (0 to 360). If the listener is outside the inner angle but still inside the outer angle, then the effective volume is scaled linearly from no scaling (when close to the inner angle) to the outer_volume value (when close or greater than the outer angle).
src_outer_volume
is the amount to scale the normal volume to when outside the outer angle. A value of 0 means the normal volume is scaled all the way to zero. A volume of 1.0 means that the normal volume isn't scaled at all (and you wouldn't hear a difference when inside or outside of the cone).
src_max_dist
is the distance from the source position to the listener position at which the sound will be clipped to silence. Note that this parameter does not affect the volume falloff curve.
src_min_dist
is the distance from the source position to the listener position at which the sound will be at maximum volume. That is, any sound that is this distance or closer to the listener will be at maximum volume.
listen_pos
specifies the effective 3D position of the listener object.
listen_face
specifies the listener object's facing direction (front vector).
listen_up
specifies the listener object's up vector.
rolloff_factor
specifies how fast 3D audio will fall off with distance. The default is 1.0, which implies no change to the "real-world" falloff speed. You can double the falloff rate by using 2.0, and you can turn off the falloff completely by using 0.0.
doppler_velocity
specifies the relative velocity of the source relative to (i.e., subtracted from) that of the listener, or NULL if no Doppler-shift calculations are desired.

Out Parameters

channel_levels
specifies a pointer to an array of at least MAX_SPEAKERS single-precision floating-point variables which will receive the calculated channel levels, from 0.0 to 1.0.
speaker_array
specifies a pointer to a variable of type MSS_SPEAKER * which will receive the address of the array of speaker locations corresponding to each channel_levels entry. (This array is internal to MSS, and is always the same for a given HDIGDRIVER).
doppler_shift
returns the factor by which the sample or stream's playback rate should be modified to implement the doppler_velocity parameter. This parameter can be NULL if no Doppler-shift calculations are desired.

Returns

The number of entries written to the channel_levels array (as well as the number of entries in the array whose location is written to *speaker_array). This will be the same as the n_logical_channels value returned by AIL_speaker_configuration.

Discussion

This function gives you the ability to position sounds in 3D space yourself without going through the normal Miles 3D sample/listener API. Its output consists of two parallel arrays, channel_levels and speaker_array, which are suitable for use as the levels and dest_speaker_indexes inputs to the AIL_set_sample_channel_levels function. Additionally, an optional Doppler-shift factor that can be applied with AIL_set_sample_playback_rate is also returned.

You can use this function in cases where you don't want MSS to maintain its own copy of an HSAMPLE's 3D state for any reason, or when you wish to modify the results of the default 3D positioning algorithm used by the library. An example might be an application requiring multiple "listeners" on the same physical platform; e.g., a split-screen multiplayer title.

For details on sound positions, cones, and distance attenuation, refer to the AIL_set_sample_3D_position, AIL_set_sample_3D_cone, AIL_set_sample_3D_distances, and AIL_set_3D_rolloff_factor functions. For simplicity's sake, most applications should use these functions rather than calling AIL_calculate_3D_channel_levels manually.

Note that the auto_3D_wet_atten parameter in AIL_set_sample_3D_distances has no corresponding functionality when AIL_calculate_3D_channel_levels is used. If you need to scale wet-reverb attenuation based on distance while using AIL_calculate_3D_channel_levels, you'll need to perform the calculation separately and pass the result to AIL_set_sample_reverb_levels.

For more information on channel-based control functions such as this one, you can review the How do I use multi-channel sound output in Miles? FAQ.

Group: Digital Audio Services
Related Functions: AIL_calculate_3D_channel_levels, AIL_set_3D_rolloff_factor, AIL_set_sample_3D_cone, AIL_set_sample_3D_distances, AIL_set_sample_3D_position, AIL_set_sample_channel_levels, AIL_set_sample_playback_rate, AIL_set_sample_reverb_levels, AIL_speaker_configuration
Related Basic Types: F32, HDIGDRIVER, MSS_SPEAKER, S32
Related Structures: MSSVECTOR3D
Related FAQs: How do I use multi-channel sound output in Miles?


MSSVECTOR3D

struct MSSVECTOR3D
{
  F32  x;
  F32  y;
  F32  z;
};

In Members

x
Contains the X-coordinate of a 3-vector.
y
Contains the Y-coordinate of a 3-vector.
z
Contains the Z-coordinate of a 3-vector.

Group: Digital Audio Services
Related Functions: AIL_calculate_3D_channel_levels, AIL_set_speaker_configuration, AIL_speaker_configuration
Related Basic Types: F32


AIL_allocate_sample_handle

The function AIL_allocate_sample_handle searches for a free sample handle and returns it to the application for use in the playback of digital audio data.

HSAMPLE AIL_allocate_sample_handle(
  HDIGDRIVER dig
);

In Parameters

dig
specifies which digital audio driver is to play the audio data associated with the sample handle.

Returns

A handle to an available sample slot, or NULL if all sample handles have already been allocated.

Discussion

Each digital audio driver, when installed, is provided with a number of sample handles. Sample handles are reusable descriptors for application audio data at any moment in time, each instance of a playing digital sample must be associated with a sample handle. The number of sample handles allocated, hence the maximum number of HSAMPLE sample handles available from AIL_allocate_sample_handle, is determined by the DIG_MIXER_CHANNELS preference. This value is normally 64, but can be set to any value by use of the AIL_set_preference function prior to driver installation.

When a per-voice digital output option such as DirectSound3D or EAX is selected, the number of available HSAMPLE handles is limited by hardware... and is typically much smaller than 64! You must check the return value from AIL_allocate_sample_handle rather than simply assuming that DIG_MIXER_CHANNELS handles will be available under all conditions.

After loading a digital audio driver, the application should allocate as many sample handles as it will require, based on the maximum number of simultaneous sound effects needed. When a sound effect is to be played, the application calls AIL_sample_status for each of its allocated sample handles, searching for one with the status SMP_DONE. This indicates that the system is either finished playing the last audio sample assigned to the sample handle, or that the sample handle has been allocated but not yet used to play a sample. Assuming an available sample handle is found, the next step is to call AIL_init_sample to prepare the sample handle for use with new data, followed by calls to set the address, size, playback volume, and other playback information. (Alternatively, file images may be passed directly to MSS with the AIL_set_sample_file and AIL_set_named_sample_file functions.) Playback of the sample data will begin when AIL_start_sample is called.

The number of simultaneously-playing samples which should be allowed by the application varies. Products which can afford to dedicate more CPU time to sound-effects processing may permit the maximum number of available sample handles to be active at once. In reality, however, the human ear has a very difficult time sorting out more than eight or ten sounds at once, and too many additional sounds are likely to waste processor time without conveying any meaningful information to the user.

Example files that use this function: SSTEST.C, DBTEST.C, DIGPLAY.C, EXAMMS.CPP

Group: Digital Audio Services
Related Functions: AIL_allocate_sample_handle, AIL_end_sample, AIL_init_sample, AIL_output_filter_driver_property, AIL_release_sample_handle, AIL_sample_buffer_available, AIL_sample_status, AIL_set_named_sample_file, AIL_set_preference, AIL_set_sample_file, AIL_start_sample, AIL_stop_sample
Related Basic Types: HDIGDRIVER, HSAMPLE, MILES_DIGITAL_STATUS, MILES_PREFERENCES
Related FAQs: How can I play two HSAMPLEs from the same memory address?, How do I play a digital sound?


AIL_release_sample_handle

The function AIL_release_sample_handle releases a sample handle previously allocated with AIL_allocate_sample_handle.

void AIL_release_sample_handle(
  HSAMPLE S
);

In Parameters

S
indicates the sample to release back to MSS.

Group: Digital Audio Services
Related Functions: AIL_allocate_sample_handle, AIL_stop_sample
Related Basic Types: HSAMPLE, void


AIL_init_sample

The function AIL_init_sample prepares a sample handle for playback of audio data.

S32 AIL_init_sample(
  HSAMPLE S,
  S32 format,
  U32 flags
);

In Parameters

S
indicates the sample handle to prepare for audio playback.
format
should be set to one of the MILES_DIGITAL_FORMAT equates.
flags
should be set to a combination of the MILES_DIGITAL_FLAGS equates.

Returns

Nonzero if the sample handle initialization succeeded; zero if a failure occurred.

Discussion

This function initializes all parameters associated with a sample handle to a set of nominal values. It should be called immediately after allocating a sample handle with AIL_allocate_sample_handle, as well as anytime an existing sample handle is used to play a new audio data sample. (Applications that play audio file images directly with AIL_set_sample_file or AIL_set_named_sample_file do not need to call AIL_init_sample at all.)

AIL_init_sample initializes the sample's playback information as follows:

The sample's status is set to SMP_DONE.

Any filters applied to the sample are disconnected.

The starting addresses of both the primary and secondary sample buffers are set to NULL, and their lengths are set to 0. Consequently, normal single-buffer playback is enabled.

The sample's position counter is set to 0 (start-of-sample).

The sample's loop counter is set to 1 (no looping).

The sample playback rate is initialized to 11025 Hz.

The sample's volume value is set to 1.0.

The sample's wet mix level is set to 0.0 and its dry mix level is set to 1.0. Occlusion, obstruction, and exclusion levels are all set to 0.0.

If the sample was under 3D positional control (i.e., the application has called AIL_set_sample_3D_position on it), it is returned to normal 2D-only mode, with its channel levels under application control. (The channel level scalars themselves are all set to 1.0.) All of the sample's internal 3D-positional data members are reset to nominal values (position at origin, up=+Y, face=+X, no emission cone, minimum distance 1.0, maximum distance 200.0, 3D auto wet-attenuation flag=TRUE).

The sample's panpot value is set to 0.5 (dead center) on a scale of 0 (hard left) to 1.0 (hard right).

The start-of-block, end-of-buffer, and end-of-sample callbacks are all canceled.

Since AIL_init_sample resets parameters such as volume, pan location, loop count, and other playback characteristics, it should appear before any calls to functions such as AIL_set_sample_volume_pan or AIL_set_sample_loop_count, or these functions will have no effect. Of course, only values which the application wishes to change from their defaults need to be set prior to calling AIL_start_sample.

None of the digital audio library functions alter or modify application sample data in any way. The same sample data may safely be passed to other drivers (or even used more than once per driver) without being reloaded into memory.

Note that stereo data is normally encountered in LR (left-to-right, in order of ascending memory location) order. If RL data from a nonstandard source is played, the DIG_PCM_ORDER flag should be set. Stereo data is not supported by the original Xbox HDIGDRIVERs when hardware 3D is enabled.

In all cases, the MSS digital playback system acts as an arbitrator between the application's data format and the limitations of the hardware in use. For example, if an attempt is made to play 16-bit 44 kHz signed stereo data with a basic mono 8-bit unsigned-PCM Sound Blaster card installed, MSS will mix the left and right channels together, scale each channel's amplitude according to the sample panpot setting, truncate the lower 8 bits of each sample, and invert the sign of the remaining 8 bits while undersampling the input data to conform to the hardware sample rate in use - all without the knowledge or intervention of the application program.

Again, it is not necessary to call this function if AIL_set_named_sample_file, AIL_set_sample_file or AIL_set_sample_info is used to play memory-resident files directly.

This function will not normally fail unless a memory-allocation failure occurs while attempting to allocate the (relatively-small) arrays associated with level-scaling and other per-channel properties. If AIL_init_sample returns 0 for failure, the AIL_last_error function may be called to obtain the error description.

Example files that use this function: SSTEST.C

Group: Digital Audio Services
Related Functions: AIL_allocate_sample_handle, AIL_init_sample, AIL_last_error, AIL_minimum_sample_buffer_size, AIL_sample_buffer_available, AIL_set_named_sample_file, AIL_set_sample_3D_position, AIL_set_sample_51_volume_pan, AIL_set_sample_address, AIL_set_sample_file, AIL_set_sample_info, AIL_set_sample_loop_count, AIL_set_sample_volume_levels, AIL_set_sample_volume_pan, AIL_start_sample, AIL_stream_info
Related Basic Types: DIGDRVSTAGE, HSAMPLE, MILES_DIGITAL_FLAGS, MILES_DIGITAL_FORMAT, MILES_DIGITAL_STATUS, S32, U32
Related FAQs: How do I set a DSP filter on a sample?, How do I use multi-channel sound output in Miles?, What's the best way to port my older Miles application to MSS 7?


AIL_set_sample_address

The function AIL_set_sample_address specifies the starting address and length for a raw data sample.

void AIL_set_sample_address(
  HSAMPLE S,
  void const * start,
  U32 len
);

In Parameters

S
indicates the sample handle whose address and length are to be set.
start
points to the beginning of the desired raw data sample in memory.
len
gives the size of the raw data sample in bytes (not samples).

Discussion

This function must be called after initializing the sample handle with AIL_init_sample, and before starting sample playback with AIL_start_sample.

It is not necessary to call this function if the AIL_set_named_sample_file, AIL_set_sample_file or AIL_set_sample_info function is used to play memory-resident .VOC or .WAV files directly.

None of the digital audio library functions alter or modify application sample data in any way. The same sample data may safely be passed to other drivers (or even used more than once per driver) without being reloaded into memory.

Example files that use this function: SSTEST.C

Group: Digital Audio Services
Related Functions: AIL_init_sample, AIL_sample_buffer_available, AIL_set_named_sample_file, AIL_set_sample_adpcm_block_size, AIL_set_sample_file, AIL_set_sample_info, AIL_set_sample_playback_rate, AIL_start_sample
Related Basic Types: HSAMPLE, U32, void, void const *


AIL_set_sample_file

The function AIL_set_sample_file initializes a sample's address, length, type, and flags to prepare for playback of memory-resident sound data.

S32 AIL_set_sample_file(
  HSAMPLE S,
  void const * file_image,
  S32 block
);

In Parameters

S
indicates the sample to prepare for .VOC or .WAV file playback.
file_image
points to the start of the file image in memory.
block
specifies a block number to play in the file. block is ignored with formats for which MSS does not support multiple blocks, such as the .WAV format. Use 0 as a default value for most applications.

Returns

0 if the file could not be parsed or if the desired block was not found; otherwise, a non-zero return value indicates the sample handle was successfully prepared for file playback.

Discussion

This function can parse a VOC file, uncompressed .WAV file, IMA ADPCM compressed .WAV file, .WAV-wrapped XMA file (on the Xbox 360), Ogg Vorbis file, .WAV-wrapped MPEG Layer 3 file, or Xbox ADPCM file on the original Xbox.

This function is identical to the AIL_allocate_file_sample function found in pre-MSS 7 releases, except that it uses an existing HSAMPLE handle rather than allocating a new one. AIL_set_sample_file is more appropriate for applications which need to maintain control over file handle management for memory-resident .VOC or .WAV file playback.

This function will process an MPEG Layer-3 file only if it is wrapped in a Microsoft WAVE header wrapper. To play a standard MP3 file image, use the AIL_set_named_sample_file function instead.

It is not necessary to call AIL_init_sample, AIL_set_sample_playback_rate, or AIL_set_sample_address when using this function. The HSAMPLE is initialized automatically by the system, just as if AIL_init_sample had been called explicitly.

Group: Digital Audio Services
Related Functions: AIL_allocate_sample_handle, AIL_init_sample, AIL_sample_buffer_available, AIL_set_named_sample_file, AIL_set_sample_3D_position, AIL_set_sample_address, AIL_set_sample_file, AIL_set_sample_info, AIL_set_sample_playback_rate, AIL_start_sample
Related Basic Types: HSAMPLE, S32, void const *
Related FAQs: How can I play two HSAMPLEs from the same memory address?, How do I play a digital sound?, How do I set a DSP filter on a sample?, How do I use multi-channel sound output in Miles?, What is MPEG Audio and MP3?, What's the best way to port my older Miles application to MSS 7?, When can I free the memory I gave to MSS?


AIL_set_named_sample_file

The function AIL_set_named_sample_file initializes a sample's address, length, type, and flags to prepare for playback of a memory-resident sound data.

S32 AIL_set_named_sample_file(
  HSAMPLE S,
  char const * filename_ext,
  void const * file_image,
  U32 file_size,
  S32 block
);

In Parameters

S
indicates the sample to prepare for file playback.
filename_ext
is a filename whose extension determines what ASI decoder to use. For example, to use the MPEG Layer 3 decoder, you would specify ".mp3" (or any string with ".mp3" in it). Future decoders will have their own extensions.
file_image
points to the start of the file image in memory.
file_size
specifies the size of the file image.
block
specifies a block number to play in the file. block is ignored with formats for which MSS does not support multiple blocks, such as the .WAV format. Use 0 as a default value for most applications.

Returns

0 if the file could not be parsed or if the desired block was not found; otherwise, a non-zero return value indicates the sample handle was successfully prepared for file playback.

Discussion

This function can parse a VOC file, uncompressed .WAV file, IMA ADPCM compressed .WAV file, MPEG Layer 3 file, mono or stereo Ogg Vorbis file, or any other supported ASI-compressed file (or Xbox ADPCM on the original Xbox).

This function is very similar to AIL_set_sample_file, except that it requires a filename extension to figure out what decoder to use. It can work with .MP3 files directly without a .WAV wrapper.

It is not necessary to call AIL_init_sample, AIL_set_sample_playback_rate, or AIL_set_sample_address when using this function. The HSAMPLE is initialized automatically by the system, just as if AIL_init_sample had been called explicitly.

Failure of this function, especially when working with MP3 files, usually means that the AIL_set_redist_directory function has not been called prior to AIL_startup, or that your MSS distribution does not include the MP3 decoder module.

Group: Digital Audio Services
Related Functions: AIL_allocate_sample_handle, AIL_init_sample, AIL_set_redist_directory, AIL_set_sample_3D_position, AIL_set_sample_address, AIL_set_sample_file, AIL_set_sample_info, AIL_set_sample_playback_rate, AIL_start_sample, AIL_startup
Related Basic Types: HSAMPLE, S32, U32, char const *, void const *
Related FAQs: How can I play two HSAMPLEs from the same memory address?, How do I play a digital sound?, How do I set a DSP filter on a sample?, How do I use multi-channel sound output in Miles?, I can't get Miles to play an MP3, XMA, or Ogg Vorbis file - what's going on?, What is MPEG Audio and MP3?, What's the best way to port my older Miles application to MSS 7?, When can I free the memory I gave to MSS?


AIL_set_sample_info

The function AIL_set_sample_info initializes a sample's address, length, type, and flags to prepare for playback of memory-resident sound data.

S32 AIL_set_sample_info(
  HSAMPLE S,
  AILSOUNDINFO const *info
);

In Parameters

S
indicates the sample to prepare for playback.
info
is a structure that contains format and address information about a sound buffer.

Returns

0 if the file could not be parsed; otherwise, a non-zero return value indicates the sample handle was successfully prepared for file playback.

Discussion

This function sets up an HSAMPLE based on the values in the AILSOUNDINFO structure. You will typically obtain a filled-out AILSOUNDINFO structure from the AIL_WAV_info function.

This function can load MPEG Layer-3 data if the format field in the AILSOUNDINFO structure is set to 85 (the standard Windows MP3 wave file id). AIL_WAV_info only parses .WAV files, so to play standard MP3 files (not .WAV-wrapped), you'll have to initialize the AILSOUNDINFO structure yourself - or just use AIL_set_named_sample_file.

It is not necessary to call AIL_init_sample, AIL_set_sample_playback_rate, or AIL_set_sample_address when using this function. The HSAMPLE is initialized automatically by the system, just as if AIL_init_sample had been called explicitly.

Group: Digital Audio Services
Related Functions: AIL_WAV_info, AIL_init_sample, AIL_set_named_sample_file, AIL_set_sample_3D_position, AIL_set_sample_address, AIL_set_sample_file, AIL_set_sample_playback_rate, AIL_start_sample
Related Basic Types: HSAMPLE, S32
Related Structures: AILSOUNDINFO
Related FAQs: How can I play two HSAMPLEs from the same memory address?, How do I play a digital sound?, How do I set a DSP filter on a sample?, How do I use multi-channel sound output in Miles?, What's the best way to port my older Miles application to MSS 7?, When can I free the memory I gave to MSS?


MILES_DIGITAL_FORMAT

The basic type MILES_DIGITAL_FORMAT describes the type of digital audio.

Fundamental Values

Value | Description
DIG_F_MONO_8 | 8-bit monaural data. (Debugger value: 0).
DIG_F_MONO_16 | 16-bit monaural data. (Debugger value: 1).
DIG_F_STEREO_8 | 8-bit stereo data. (Debugger value: 2).
DIG_F_STEREO_16 | 16-bit stereo data. (Debugger value: 3).
DIG_F_ADPCM_MONO_16 | IMA ADPCM mono data - always expands to 16-bit. (Debugger value: 5).
DIG_F_ADPCM_STEREO_16 | IMA ADPCM stereo data - always expands to 16-bit. (Debugger value: 7).
DIG_F_XBOX_ADPCM_MONO_16 | XBOX ADPCM mono data - always expands to 16-bit. (Debugger value: 9). Only available on original Xbox.
DIG_F_XBOX_ADPCM_STEREO_16 | XBOX ADPCM stereo data - always expands to 16-bit. (Debugger value: 11). Only available on original Xbox.
DIG_F_STEREO_MASK | Bitmask to determine if the format is any of the stereo formats. (Debugger value: 2).
DIG_F_16BITS_MASK | Bitmask to determine if the format is any of the 16-bit formats. (Debugger value: 1).
DIG_F_MULTICHANNEL_MASK | Bitmask to determine if the hardware was opened for a discrete format with more than 2 channels. (Debugger value: 16).
DIG_F_OUTPUT_FILTER_IN_USE | Bitmask to determine if a per-voice output filter such as DirectSound3D or EAX is in use. (Debugger value: 32).

Group: Digital Audio Services
Related Functions: AIL_WAV_file_fss_write, AIL_WAV_file_write, AIL_digital_configuration, AIL_init_sample, AIL_process_digital_audio, AIL_size_processed_digital_audio
Related Structures: AIL_INPUT_INFO


MILES_DIGITAL_FLAGS

The basic type MILES_DIGITAL_FLAGS describes the layout of digital audio.

Fundamental Values

Value | Description
DIG_PCM_ORDER | If present, stereo data is in RL order; else LR.

Group: Digital Audio Services
Related Functions: AIL_init_sample


AIL_start_sample

The function AIL_start_sample starts playback of a sample from its beginning.

void AIL_start_sample(
  HSAMPLE S
);

In Parameters

S
indicates the sample to start playing.

Discussion

If a conventional single-buffered sample is already playing, it will be restarted from the beginning by this function. To begin playback at a specific position, set the position with AIL_set_sample_position and call AIL_resume_sample instead of AIL_start_sample.

At a minimum, the sample handle must be initialized with AIL_init_sample, AIL_set_sample_info, AIL_set_sample_file, or AIL_set_named_sample_file prior to starting playback. If you used AIL_init_sample to initialize a handle to a raw data sample, the sample's address and length should be specified with a call to AIL_set_sample_address. If any of the other sample-initialization functions were called, however, only AIL_start_sample needs to be called in order to begin playback.

After submitting low-level streaming data with AIL_load_sample_buffer, it's necessary to call AIL_start_sample at least once to initiate playback of the submitted buffers. There's no need to check the playback status first in this case -- AIL_start_sample has no effect when called on a low-level streamed sample that's already playing. (This behavior is new in MSS 7.)

Under Win32 and Win64 on waveOut, the MSS architecture permits a sound effect to be started with essentially zero latency as long as no other sound effects are currently being played. On the other hand, latency times incurred for samples which must be injected into an already-running mixer stream may be much higher than even the worst figures obtained in the DOS version of MSS. Consequently, it is important when beginning video playback or any other latency-critical activity to ensure that no previous digital audio effects have been played for at least a few hundred milliseconds prior to starting playback of the critical sound effect or stream.

On a Win32 or Win64 system with a native DirectSound driver installed, MSS will take advantage of the high-performance Microsoft DirectSound buffer mechanism to eliminate these latency problems.

On MacOS, Miles has been written so that digital latency will rarely (if ever) exceed 100 milliseconds and will never exceed 140 milliseconds regardless of the speed of your machine. Just like waveOut, though, Sound Manager imposes some amount of its own latency as well (exactly how much depends on the machine and version of Sound Manager).

Example files that use this function: SSTEST.C, DBTEST.C, DIGPLAY.C, EXAMMS.CPP

Group: Digital Audio Services
Related Functions: AIL_allocate_sample_handle, AIL_end_sample, AIL_get_DirectSound_info, AIL_init_sample, AIL_load_sample_buffer, AIL_register_EOS_callback, AIL_register_SOB_callback, AIL_resume_sample, AIL_sample_buffer_available, AIL_set_named_sample_file, AIL_set_sample_address, AIL_set_sample_file, AIL_set_sample_info, AIL_set_sample_position, AIL_start_sample, AIL_stop_sample
Related Basic Types: HSAMPLE, void
Related FAQs: How do I play a digital sound?, How do I start an audio file somewhere in the middle?, What's the best way to port my older Miles application to MSS 7?


AIL_stop_sample

The function AIL_stop_sample stops playback of a sample.

void AIL_stop_sample(
  HSAMPLE S
);

In Parameters

S
indicates the sample to stop playing.

Discussion

If desired, sample playback may be resumed from the current position with a call to AIL_resume_sample.

It is not necessary to stop playback of a sample with this function before restarting it with AIL_start_sample, or releasing its handle with AIL_release_sample_handle.

After stopping playback of a sample with AIL_stop_sample, calls to the AIL_sample_status function will return SMP_STOPPED, not SMP_DONE. If the application manages its allocated sample handles by reusing handles whose status is SMP_DONE, as described in the remarks for the AIL_allocate_sample_handle function, AIL_end_sample may be more appropriate than AIL_stop_sample. AIL_end_sample is similar to AIL_stop_sample, but it resets the sample's status to SMP_DONE instead of SMP_STOPPED.

AIL_stop_sample has no effect on samples whose status is not SMP_PLAYING.

Group: Digital Audio Services
Related Functions: AIL_allocate_sample_handle, AIL_end_sample, AIL_release_sample_handle, AIL_resume_sample, AIL_sample_buffer_available, AIL_set_sample_loop_count, AIL_start_sample, AIL_stop_sample
Related Basic Types: HSAMPLE, MILES_DIGITAL_STATUS, void


AIL_resume_sample

The function AIL_resume_sample resumes playback of a sample which was previously stopped.

void AIL_resume_sample(
  HSAMPLE S
);

In Parameters

S
indicates the sample to resume playing.

Discussion

AIL_resume_sample is usually used to resume playback that has been stopped with a call to AIL_stop_sample, but it can also be used to start a sample without the playback position being reset to the beginning of the sound.

Group: Digital Audio Services
Related Functions: AIL_end_sample, AIL_resume_sample, AIL_start_sample, AIL_stop_sample
Related Basic Types: HSAMPLE, void
Related FAQs: How do I start an audio file somewhere in the middle?


AIL_end_sample

The function AIL_end_sample terminates playback of a sample, setting its status to SMP_DONE.

void AIL_end_sample(
  HSAMPLE S
);

In Parameters

S
indicates the sample to terminate.

Discussion

After stopping playback of a sample with AIL_end_sample, calls to the AIL_sample_status function will return SMP_DONE, not SMP_STOPPED. If the application manages its allocated sample handles by reusing handles whose status is SMP_DONE, as described in the remarks for the AIL_allocate_sample_handle function, AIL_end_sample may be more appropriate than AIL_stop_sample. AIL_end_sample is similar to AIL_stop_sample, but it resets the sample's status to SMP_DONE instead of SMP_STOPPED.

Example files that use this function: SSTEST.C

Group: Digital Audio Services
Related Functions: AIL_allocate_sample_handle, AIL_end_sample, AIL_resume_sample, AIL_sample_buffer_available, AIL_sample_status, AIL_set_sample_loop_count, AIL_start_sample, AIL_stop_sample
Related Basic Types: HSAMPLE, MILES_DIGITAL_STATUS, void
Related FAQs: When can I free the memory I gave to MSS?


AIL_set_sample_playback_rate

The function AIL_set_sample_playback_rate sets a sample's playback rate in hertz.

void AIL_set_sample_playback_rate(
  HSAMPLE S,
  S32 playback_rate
);

In Parameters

S
indicates the sample whose playback rate is to be set.
playback_rate
specifies the number of samples per second at which to play the sample data.

Discussion

An individual audio data sample may be played by the application at any desired rate, which imply that a number of sample points are skipped or repeated during playback, respectively. Undersampling is used when the playback rate is greater than the recorded rate, and results in a "fast-forward" effect because a number of sample points must be skipped to achieve the higher playback rate. Conversely, oversampling occurs when the playback rate is lower than the recorded rate. In this case, some sample bytes or words must be played more than once before moving on to the next sample point, causing a "dragging" or slowdown effect.

Internally, MSS uses oversampling and undersampling to resolve differences between application data rates and hardware rates. Distortion due to oversampling, in particular, may result when low-frequency data is played at high hardware data rates. Abrupt transitions between repeated sample point values can introduce unwanted high-frequency components which are not effectively attenuated by the hardware's antialiasing filters. On the other hand, the same antialiasing filters may clip treble frequencies from the sample data if the hardware's rate is significantly lower than the application's data rate.

For the reasons mentioned above, the best audio quality will always be achieved when the driver's hardware data rate is matched as closely as possible to the application's sample data rate. If most of an application's sample data was recorded at a rate of 11025 Hz, for example, it would be a good idea to use 11025 Hz in the call to AIL_open_digital_driver. This will ensure that most of the samples are played without introducing distortion or attenuating treble frequencies. Any samples played at frequencies other than 11025 Hz will be undersampled or oversampled to conform to the hardware rate of 11025 Hz established by the AIL_set_preference call. If the hardware or driver in use does not support a 11025 Hz rate, the closest supported hardware rate will be selected, and the application's data will be resampled accordingly.

It is not necessary to call this function if AIL_set_named_sample_file, AIL_set_sample_file, or AIL_set_sample_info is used to play memory-resident .VOC or .WAV files directly.

Example files that use this function: SSTEST.C

Group: Digital Audio Services
Related Functions: AIL_calculate_3D_channel_levels, AIL_open_digital_driver, AIL_sample_buffer_available, AIL_sample_playback_rate, AIL_set_named_sample_file, AIL_set_preference, AIL_set_sample_address, AIL_set_sample_file, AIL_set_sample_info
Related Basic Types: HSAMPLE, MILES_PREFERENCES, S32, void


AIL_sample_playback_rate

The function AIL_sample_playback_rate returns the current sample playback rate.

S32 AIL_sample_playback_rate(
  HSAMPLE S
);

In Parameters

S
indicates the sample handle whose playback rate is to be returned.

Returns

The sample's playback rate in samples per second.

Discussion

See AIL_set_sample_playback_rate for more information.

Group: Digital Audio Services
Related Functions: AIL_set_sample_playback_rate
Related Basic Types: HSAMPLE, S32


AIL_set_sample_volume_pan

The function AIL_set_sample_volume_pan controls a sample's playback volume level and pan.

void AIL_set_sample_volume_pan(
  HSAMPLE S,
  F32 volume,
  F32 pan
);

In Parameters

S
indicates the sample whose volume is to be set.
volume
is a volume level from 0 (minimum) to 1.0 (maximum) in loudness (0.5 is 10 dB down).
pan
is a power pan level from 0 (hard-left) to 1.0 (hard-right).

Discussion

The volume setting is linear in loudness (not amplitude) - using 0.5 is equivalent to 10 dB down. Use AIL_set_sample_volume_levels to set volumes linear in amplitude.

All sample volume scaling occurs at full sample precision.

When a sample handle is initialized by AIL_init_sample, the sample's volume value is set to 1.0 and the pan value is set to 0.5.

The pan setting is a power pan (DLS standard). Sliding the pan from left to right adjusts the internal volume as well, such that the sound feels like it remains at the same power as it pans across the speakers.

Pan has no effect when mono audio data is played with mono sound ouput. When mono audio data is played with stereo hardware, the panpot setting determines the sample's location in the stereo field. When stereo data is played with stereo hardware, the panpot setting acts as a stereo balance control, determining the relative volume levels in the left and right channels. At 0.5, the balance control is considered at midrange, and no attenuation takes place in either channel.

You won't hear pan changes unless you open the digital driver in modes with 2 or more output channels. Make sure you use 2 channels, or a multispeaker-compatible MSS_MC_SPEC value, in your call to AIL_open_digital_driver.

Finally, note that for mono samples that will undergo 3D positioning, you should always use a pan value of 0.5. Any other pan value will cause the 3D positioner to favor one speaker or the other in each successive multichannel pair.

Example files that use this function: SSTEST.C

Group: Digital Audio Services
Related Functions: AIL_digital_master_volume_level, AIL_init_sample, AIL_open_digital_driver, AIL_sample_51_volume_pan, AIL_sample_buffer_available, AIL_sample_volume_pan, AIL_set_digital_master_volume_level, AIL_set_sample_51_volume_pan, AIL_set_sample_low_pass_cut_off, AIL_set_sample_reverb_levels, AIL_set_sample_volume_levels
Related Basic Types: F32, HSAMPLE, MSS_MC_SPEC, void
Related FAQs: How do I use multi-channel sound output in Miles?, I used an older version of Miles and now my volume and pan calls are weird - what's going on? And what's with the two types of volume functions?


AIL_sample_volume_pan

The function AIL_sample_volume_pan returns the current sample volume and pan, from 0 to 1.0.

void AIL_sample_volume_pan(
  HSAMPLE S,
  F32 *volume,
  F32 *pan
);

In Parameters

S
indicates the sample whose volume is to be retrieved.

Out Parameters

volume
returns a volume level from 0 (minimum) to 1.0 (maximum) in loudness (0.5 is 10 dB down).
pan
returns a power pan level from 0 (hard-left) to 1.0 (hard-right).

Discussion

See AIL_set_sample_volume_pan for more information.

Group: Digital Audio Services
Related Functions: AIL_digital_master_volume_level, AIL_sample_51_volume_pan, AIL_sample_low_pass_cut_off, AIL_sample_reverb_levels, AIL_set_digital_master_volume_level, AIL_set_sample_51_volume_pan, AIL_set_sample_volume_levels, AIL_set_sample_volume_pan
Related Basic Types: F32, HSAMPLE, void
Related FAQs: I used an older version of Miles and now my volume and pan calls are weird - what's going on? And what's with the two types of volume functions?


AIL_set_sample_reverb_levels

The function AIL_set_sample_reverb_levels changes the reverb levels of a digital audio sample.

void AIL_set_sample_reverb_levels(
  HSAMPLE S,
  F32 dry_level,
  F32 wet_level
);

In Parameters

S
indicates the sample whose reverb is to be set.
dry_level
specifies the level of the dry sound signal (the non-reverbed sound). The range is 0.0 for no output, 1.0 for full output.
wet_level
specifies the level of the wet sound signal (the reverberations). The range is 0.0 for no output, 1.0 for full output.

Discussion

This function controls the reverb levels applied by the AIL_set_digital_master_reverb. These levels are linear scalars, where each doubling of the level value represents a 6-dB change in the wet or dry level. For instance, a wet_level or dry_level value of 0.5 is 6 dB quieter than a value of 1.0, and 0.25 would be 12 dB quieter than 1.0.

Reverb requires CPU time to apply, but it's pretty minimal. You can monitor the CPU use with the AIL_digital_CPU_percent function.

You can use this function even if you haven't started playback yet.

Group: Digital Audio Services
Related Functions: AIL_calculate_3D_channel_levels, AIL_digital_CPU_percent, AIL_digital_master_reverb_levels, AIL_sample_reverb_levels, AIL_sample_volume_levels, AIL_set_digital_master_reverb, AIL_set_digital_master_reverb_levels, AIL_set_room_type, AIL_set_sample_51_volume_levels, AIL_set_sample_51_volume_pan, AIL_set_sample_volume_levels, AIL_set_sample_volume_pan
Related Basic Types: F32, HSAMPLE, void
Related FAQs: How do I set an environmental reverb room style?, What's the best way to port my older Miles application to MSS 7?


AIL_sample_reverb_levels

The function AIL_sample_reverb_levels retrieves the reverb levels of a digital audio sample.

void AIL_sample_reverb_levels(
  HSAMPLE S,
  F32 *dry_level,
  F32 *wet_level
);

In Parameters

S
indicates the sample whose reverb settings are to be retrieved.

Out Parameters

dry_level
returns the level of the dry sound signal (the non-reverbed sound). The range is 0.0 for no output, 1.0 for full output.
wet_level
returns the level of the wet sound signal (the reverberations). The range is 0.0 for no output, 1.0 for full output.

Discussion

The reverb levels default to 1.0f for the dry level and 0.0f for the wet_level.

Reverb requires CPU time to apply, but it's pretty minimal. You can monitor the CPU use with the AIL_digital_CPU_percent function.

Group: Digital Audio Services
Related Functions: AIL_digital_CPU_percent, AIL_digital_master_reverb_levels, AIL_sample_51_volume_levels, AIL_sample_51_volume_pan, AIL_sample_volume_levels, AIL_sample_volume_pan, AIL_set_digital_master_reverb_levels, AIL_set_sample_reverb_levels
Related Basic Types: F32, HSAMPLE, void


AIL_set_sample_low_pass_cut_off

The function AIL_set_sample_low_pass_cut_off applies a low-pass filter to the digital audio sample.

void AIL_set_sample_low_pass_cut_off(
  HSAMPLE sample,
  F32 cut_off
);

In Parameters

sample
specifies the digital sample that you wish to control.
cut_off
specifies the low-pass filter cutoff frequency. The range is 0.0 to 1.0, given as a fraction of the sample's Nyquist rate.

Discussion

This function allows you to set a low-pass filter on any digital sample (whether uncompressed or compressed). A low-pass filter attenuates frequencies above the cutoff frequency.

The default low-pass cutoff is 1.0 (allowing all frequencies to pass).

The range is 0.0 to 1.0, given as a fraction of the sample's Nyquist rate (which is half the sample rate). For example, if you have a 44100 Hz sample, then the Nyquist rate is 22050 Hz. If you then set a 0.5 cut off, only frequencies under 11025 Hz will be perceived at close to their full amplitude.

In software-mixing contexts, the AIL_set_sample_low_pass_cut_off function is used to implement occlusion, so the two functions cannot be used together on the same HSAMPLE.

There is almost no CPU hit at all with this filter. There is no CPU hit at all on the original Xbox, but the hardware low-pass filter only supports frequencies from 30 to 8000 Hz.

Group: Digital Audio Services
Related Sections: Low-Pass Filter
Related Functions: AIL_sample_low_pass_cut_off, AIL_set_sample_low_pass_cut_off, AIL_set_sample_volume_levels, AIL_set_sample_volume_pan
Related Basic Types: F32, HSAMPLE, void
Related FAQs: How do I apply a low-pass filter?


AIL_sample_low_pass_cut_off

The function AIL_sample_low_pass_cut_off retrieves the current low-pass cutoff setting.

F32 AIL_sample_low_pass_cut_off(
  HSAMPLE sample
);

In Parameters

sample
specifies the digital sample that you wish to query.

Returns

returns the current low-pass filter cutoff frequency. The range is 0.0 to 1.0, given as a fraction of the sample's Nyquist rate.

Discussion

A low-pass filter attenuates frequencies above the cutoff frequency.

The default low-pass cutoff is 1.0 (allowing all frequencies to pass).

The range is 0.0 to 1.0, given as a fraction of the sample's Nyquist rate (which is half the sample rate). For example, if you have a 44100 Hz sample, then the Nyquist rate is 22050 Hz. If you then set a 0.5 cutoff factor, only frequencies under 11025 Hz will be perceived near their original amplitude.

There is almost no CPU hit at all with this filter. There is no CPU hit at all on the original Xbox, but the hardware low-pass filter only supports frequencies from 30 to 8000 Hz.

Group: Digital Audio Services
Related Functions: AIL_sample_volume_levels, AIL_sample_volume_pan, AIL_set_sample_low_pass_cut_off
Related Basic Types: F32, HSAMPLE


AIL_set_sample_51_volume_pan

The function AIL_set_sample_51_volume_pan controls a sample's playback volume and pan values when using multichannel discrete output modes.

void AIL_set_sample_51_volume_pan(
  HSAMPLE S,
  F32 volume,
  F32 pan,
  F32 fb_pan,
  F32 center_scale,
  F32 sub_scale
);

In Parameters

S
indicates the sample whose volume is to be set.
volume
is a volume level from 0 (minimum) to 1.0 (maximum) in loudness (0.5 is 10 dB down).
pan
is a power pan level from 0 (hard-left) to 1.0 (hard-right).
fb_pan
is a front to back power pan level from 0 (front) to 1.0 (back).
center_scale
is a volume multipler for the center channel from 0 (minimum) to 1.0 (maximum) - this is multiplied by the volume level above.
sub_scale
is a volume multipler for the subwoofer channel from 0 (minimum) to 1.0 (maximum) - this is multiplied by the volume level above.

Discussion

This function is available on all software-mixed platforms, as well as on the Xbox. Parameters that don't correspond to an available speaker in the HDIGDRIVER's current mode will be ignored.

Levels calculated by this function are multiplied with any values arising from 3D positioning and/or the use of the AIL_set_sample_channel_levels function. This function is intended primarily for use as a "shortcut" for multichannel applications, notably on the Xbox and Xbox 360 platforms (which are always treated as 5.1-channel platforms by Miles). The volume setting is linear in loudness (not amplitude) - using 0.5 is equivalent to 10 dB down. Use AIL_set_sample_51_volume_levels to set volumes linear in amplitude.

All sample volume scaling occurs at full sample precision.

When a sample handle is initialized by AIL_init_sample, the sample's volume value is set to 1.0 and the pan values are set to 0.5.

The pan setting is a power-pan function (DLS standard). Sliding the pan from left to right adjusts the internal volume as well, such that the sound appears to remain at the same audible level as it pans across the speakers.

Group: Digital Audio Services
Related Sections: Sound under Xbox, Sound under Xbox 360
Related Functions: AIL_init_sample, AIL_sample_51_volume_pan, AIL_sample_volume_pan, AIL_set_sample_51_volume_levels, AIL_set_sample_channel_levels, AIL_set_sample_reverb_levels, AIL_set_sample_volume_pan
Related Basic Types: F32, HSAMPLE, void


AIL_sample_51_volume_pan

The function AIL_sample_51_volume_pan returns the current sample 5.1 volumes and pan, from 0 to 1.0, resulting from a prior call to AIL_set_sample_51_volume_pan or AIL_set_sample_51_volume_levels.

void AIL_sample_51_volume_pan(
  HSAMPLE S,
  F32 *volume,
  F32 *pan,
  F32 *fb_pan,
  F32 *center_scale,
  F32 *sub_scale
);

In Parameters

S
indicates the sample whose volume is to be retrieved.

Out Parameters

volume
returns a volume level from 0 (minimum) to 1.0 (maximum) in loudness (0.5 is 10 dB down).
pan
returns a power pan level from 0 (hard-left) to 1.0 (hard-right).
fb_pan
returns a front to back power pan level from 0 (front) to 1.0 (back).
center_scale
returns a center channel level from 0 (minimum) to 1.0 (maximum).
sub_scale
returns a subwoofer channel level from 0 (minimum) to 1.0 (maximum).

Discussion

This function is available on all software-mixed platforms, as well as on the Xbox. Parameters that don't correspond to an available speaker in the HDIGDRIVER's current mode will be ignored.

Levels calculated by this function are multiplied with any values arising from 3D positioning and/or the use of the AIL_set_sample_channel_levels function. This function is intended primarily for use as a "shortcut" for multichannel applications, notably on the Xbox and Xbox 360 platforms (which are always treated as 5.1-channel platforms by Miles).

See AIL_set_sample_volume_pan for more information.

Group: Digital Audio Services
Related Functions: AIL_sample_reverb_levels, AIL_sample_volume_pan, AIL_set_sample_51_volume_levels, AIL_set_sample_51_volume_pan, AIL_set_sample_channel_levels, AIL_set_sample_volume_pan
Related Basic Types: F32, HSAMPLE, void


AIL_set_sample_volume_levels

The function AIL_set_sample_volume_levels controls a sample's playback volume levels.

void AIL_set_sample_volume_levels(
  HSAMPLE S,
  F32 left_level,
  F32 right_level
);

In Parameters

S
indicates the sample whose volume is to be set.
left_level
is the left speaker volume level from 0 (minimum) to 1.0 (maximum).
right_level
is the right speaker volume level from 0 (minimum) to 1.0 (maximum).

Discussion

This volume setting is linear in amplitude - using 0.5 is equivalent to 6 dB down. Use AIL_set_sample_volume_pan to set volumes linear in loudness.

All sample volume scaling occurs at full sample precision.

When a sample handle is initialized by AIL_init_sample, the sample's volume left and right values are both 0.881.

For mono samples that will undergo 3D positioning, you should always set the left and right volume levels equal to each other. Any difference will cause the 3D positioner to favor one speaker or the other in each successive multichannel pair.

Example files that use this function: SSTEST.C

Group: Digital Audio Services
Related Functions: AIL_init_sample, AIL_sample_volume_levels, AIL_sample_volume_pan, AIL_set_sample_low_pass_cut_off, AIL_set_sample_reverb_levels, AIL_set_sample_volume_pan
Related Basic Types: F32, HSAMPLE, void
Related FAQs: How do I use multi-channel sound output in Miles?, I used an older version of Miles and now my volume and pan calls are weird - what's going on? And what's with the two types of volume functions?


AIL_sample_volume_levels

The function AIL_sample_volume_levels returns the current sample volumes, from 0 to 1.0.

void AIL_sample_volume_levels(
  HSAMPLE S,
  F32 *left_level,
  F32 *right_level
);

In Parameters

S
indicates the sample whose volume is to be retrieved.

Out Parameters

left_level
returns the left speaker volume level from 0 (minimum) to 1.0 (maximum).
right_level
returns the right speaker volume level from 0 (minimum) to 1.0 (maximum).

Discussion

See AIL_set_sample_volume_levels for more information.

Group: Digital Audio Services
Related Functions: AIL_sample_low_pass_cut_off, AIL_sample_reverb_levels, AIL_set_sample_reverb_levels, AIL_set_sample_volume_levels
Related Basic Types: F32, HSAMPLE, void
Related FAQs: I used an older version of Miles and now my volume and pan calls are weird - what's going on? And what's with the two types of volume functions?


AIL_set_sample_channel_levels

The function AIL_set_sample_channel_levels scales the output contribution from each source channel in the specified HSAMPLE to each speaker.

void AIL_set_sample_channel_levels(
  HSAMPLE S,
  MSS_SPEAKER const * source_speaker_indexes,
  MSS_SPEAKER const * dest_speaker_indexes,
  F32 const * level_array,
  S32 n_levels
);

In Parameters

S
indicates the HSAMPLE for which the channel levels are to be set.
source_speaker_indexes
specifies an array of one or more channels in the source data.
dest_speaker_indexes
specifies an array of one or more speakers.
level_array
specifies an array of coefficients from 0.0 to 1.0 which will scale the output of the HSAMPLE at each combination of source/destination channels specified by the corresponding source_speaker_indexes and dest_speaker_indexes entries.
n_levels
specifies the number of entries in level_array, source_speaker_indexes, and dest_speaker_indexes.

Discussion

This function allows the application to provide scale factors that determine the routing between the specified sample's source channels and the driver's logical output channels. The input arrays must all have the same number of elements, specified by n_levels. They can be as simple as three single-entry arrays that establish the level of a single channel at a single speaker, or a completely-general matrix where audio from any number of source channels is steered to any number of destination speakers. References to channels that are not present in the source or destination will simply be ignored.

Here's an example of how you might implement a simple downmix function that maps the center channel in a 3.0-channel source sample to the front-left and front-right speakers in a stereo output configuration:

  MSS_SPEAKER downmix_source_list[] = { MSS_SPEAKER_FRONT_CENTER, MSS_SPEAKER_FRONT_CENTER };
  MSS_SPEAKER downmix_dest_list[] =   { MSS_SPEAKER_FRONT_LEFT,   MSS_SPEAKER_FRONT_RIGHT  };
  F32         downmix_level_list[] =  { 0.5F,                     0.5F                     };
  AIL_set_sample_channel_levels(S,
                                downmix_source_list,
                                downmix_dest_list,
                                downmix_level_list,
                                2);

This function will have no effect with per-voice hardware drivers that don't use the Miles software mixer. Currently, this applies only to the Xbox 1 and the MSS_MC_DIRECTSOUND3D and MSS_MC_EAX? values from the MSS_MC_SPEC list.

For a detailed understanding of per-channel level control, you should carefully review the How do I use multi-channel sound output in Miles? FAQ before attempting to use this function.

Most applications won't need to set channel levels explicitly. To handle mono samples in a multichannel environment, it's often best to let Miles' built-in 3D positioning code do the work for you! (If an HSAMPLE has been assigned a 3D position with AIL_set_sample_3D_position, any values the application writes to the channel-level array will be multiplied with the results of the 3D-positioning calculations.)

This function is not recommended for use with stereo samples. Standard stereo samples cannot be cross-routed (left-to-right and vice versa) with this function, since stereo source data has its own dedicated mixer path. Multichannel samples, however, can be routed arbitrarily, since they're processed internally as a stack of discrete mono samples.

Group: Digital Audio Services
Related Functions: AIL_calculate_3D_channel_levels, AIL_open_stream, AIL_sample_51_volume_levels, AIL_sample_51_volume_pan, AIL_sample_channel_levels, AIL_sample_output_levels, AIL_set_sample_3D_position, AIL_set_sample_51_volume_levels, AIL_set_sample_51_volume_pan
Related Basic Types: F32, HSAMPLE, MSS_MC_SPEC, MSS_SPEAKER, S32, void
Related FAQs: How do I use multi-channel sound output in Miles?


AIL_sample_channel_levels

The function AIL_sample_channel_levels returns an array of level-scaling factors for one or more combinations of source channels and destination speakers.

void AIL_sample_channel_levels(
  HSAMPLE S,
  MSS_SPEAKER const * source_speaker_indexes,
  MSS_SPEAKER const * dest_speaker_indexes,
  F32 *level_array,
  S32 n_levels
);

In Parameters

S
indicates the HSAMPLE for which the channel levels are to be retrieved.
source_speaker_indexes
specifies an array of one or more channels in the source data.
dest_speaker_indexes
specifies an array of one or more speakers.
n_levels
specifies the number of entries in level_array, source_speaker_indexes, and dest_speaker_indexes.

Out Parameters

level_array
an array of coefficients from 0.0 to 1.0 which will scale the output of the HSAMPLE at each combination of source/destination channels specified by the corresponding source_speaker_indexes and dest_speaker_indexes entries.

Discussion

This function lets you retrieve the per-channel volume scale factors passed to AIL_set_sample_channel_levels by the application or established at sample-initialization time.

This function will have no effect with per-voice hardware drivers that don't use the Miles software mixer. Currently, this applies only to the Xbox 1 and MSS_MC_DIRECTSOUND3D and MSS_MC_EAX? values from the MSS_MC_SPEC list.

For a detailed understanding of per-channel level control, you should carefully review the How do I use multi-channel sound output in Miles? FAQ before attempting to use this function.

Group: Digital Audio Services
Related Functions: AIL_set_sample_channel_levels
Related Basic Types: F32, HSAMPLE, MSS_MC_SPEC, MSS_SPEAKER, S32, void
Related FAQs: How do I use multi-channel sound output in Miles?


AIL_sample_output_levels

The function AIL_sample_output_levels returns the final mixer level-scaling factors for one or more combinations of source channels and destination speakers.

void AIL_sample_output_levels(
  HSAMPLE S,
  MSS_SPEAKER const * source_speaker_indexes,
  MSS_SPEAKER const * dest_speaker_indexes,
  F32 *level_array,
  S32 n_levels
);

In Parameters

S
indicates the HSAMPLE for which the mixer output levels are to be retrieved.
source_speaker_indexes
specifies an array of one or more channels in the source data.
dest_speaker_indexes
specifies an array of one or more speakers.
n_levels
specifies the number of entries in level_array, source_speaker_indexes, and dest_speaker_indexes.

Out Parameters

level_array
an array of coefficients from 0.0 to 1.0 which represent the amplitude levels of the given sample channels at the given speakers.

Discussion

This function lets you retrieve the per-channel volume scale factors that result from all dry-path attenuation processes inside MSS. These factors are derived from the products of 3D distance and cone attenuation (if any), obstruction, per-sample and per-speaker reverb dry levels, volume/pan control, the DIG_LEVEL_RAMP_SAMPLES process, and per-sample channel levels associated with the AIL_set_sample_channel_levels function. (They do not include any modifications to the actual sample values performed by DSP pipeline filters.)

This function will have no effect with per-voice hardware drivers that don't use the Miles software mixer. Currently, this applies only to the Xbox 1 and MSS_MC_DIRECTSOUND3D and MSS_MC_EAX? values from the MSS_MC_SPEC list.

Uses for this function include dynamic prioritization of samples and audio pipeline debugging.

For a detailed understanding of per-channel level control, you should carefully review the How do I use multi-channel sound output in Miles? FAQ before attempting to use this function. You may also wish to examine the Digital Audio Pipeline section.

Group: Digital Audio Services, The Digital Audio Pipeline
Related Functions: AIL_set_sample_channel_levels
Related Basic Types: F32, HSAMPLE, MILES_PREFERENCES, MSS_MC_SPEC, MSS_SPEAKER, S32, void
Related FAQs: How do I use multi-channel sound output in Miles?


AIL_set_sample_51_volume_levels

The function AIL_set_sample_51_volume_levels controls a sample's playback volume levels when using multichannel discrete output modes.

void AIL_set_sample_51_volume_levels(
  HSAMPLE S,
  F32 front_left_level,
  F32 front_right_level,
  F32 back_left_level,
  F32 back_right_level,
  F32 center_level,
  F32 sub_level
);

In Parameters

S
indicates the sample whose volume is to be set.
front_left_level
is the left speaker volume level from 0 (minimum) to 1.0 (maximum).
front_right_level
is the right speaker volume level from 0 (minimum) to 1.0 (maximum).
back_left_level
is the left speaker volume level from 0 (minimum) to 1.0 (maximum).
back_right_level
is the right speaker volume level from 0 (minimum) to 1.0 (maximum).
center_level
is the center speaker volume level from 0 (minimum) to 1.0 (maximum).
sub_level
is the subwoofer speaker volume level from 0 (minimum) to 1.0 (maximum).

Discussion

This function is available on all software-mixed platforms, as well as on the Xbox. Parameters that don't correspond to an available speaker in the HDIGDRIVER's current mode will be ignored.

Levels calculated by this function are multiplied with any values arising from 3D positioning or the use of the AIL_set_sample_channel_levels function. This function is intended primarily for use as a "shortcut" for multichannel applications, notably on the Xbox and Xbox 360 platforms (which are always treated as 5.1-channel platforms by Miles). This volume setting is linear in amplitude - using 0.5 is equivalent to 6 dB down. Use AIL_set_sample_51_volume_pan to set volumes linear in loudness.

All sample volume-scaling occurs at full sample precision.

Group: Digital Audio Services
Related Sections: Sound under Xbox, Sound under Xbox 360
Related Functions: AIL_sample_51_volume_levels, AIL_sample_51_volume_pan, AIL_set_sample_51_volume_pan, AIL_set_sample_channel_levels, AIL_set_sample_reverb_levels
Related Basic Types: F32, HSAMPLE, void


AIL_sample_51_volume_levels

The function AIL_sample_51_volume_levels returns the current sample 5.1 volumes, from 0 to 1.0, on discrete multichannel platforms.

void AIL_sample_51_volume_levels(
  HSAMPLE S,
  F32 *front_left_level,
  F32 *front_right_level,
  F32 *back_left_level,
  F32 *back_right_level,
  F32 *center_level,
  F32 *sub_level
);

In Parameters

S
indicates the sample whose volume is to be retrieved.

Out Parameters

front_left_level
returns the front left speaker volume level from 0 (minimum) to 1.0 (maximum).
front_right_level
returns the front right speaker volume level from 0 (minimum) to 1.0 (maximum).
back_left_level
returns the back left speaker volume level from 0 (minimum) to 1.0 (maximum).
back_right_level
returns the back right speaker volume level from 0 (minimum) to 1.0 (maximum).
center_level
returns the center speaker volume level from 0 (minimum) to 1.0 (maximum).
sub_level
returns the subwoofer speaker volume level from 0 (minimum) to 1.0 (maximum).

Discussion

This function is available on all software-mixed platforms, as well as on the Xbox. Parameters that don't correspond to an available speaker in the HDIGDRIVER's current mode will be ignored.

Levels calculated by this function are multiplied with any values arising from 3D positioning or the use of the AIL_set_sample_channel_levels function. This function is intended primarily for use as a "shortcut" for dedicated 5.1-channel applications, notably on the Xbox and Xbox 360 platforms (which are always treated as 5.1-channel platforms by Miles).

Group: Digital Audio Services
Related Functions: AIL_sample_reverb_levels, AIL_set_sample_51_volume_levels, AIL_set_sample_channel_levels
Related Basic Types: F32, HSAMPLE, void


AIL_set_sample_3D_distances

The function AIL_set_sample_3D_distances sets the minimum and maximum distances for a given sample handle.

void AIL_set_sample_3D_distances(
  HSAMPLE S,
  F32 max_dist,
  F32 min_dist,
  S32 auto_3D_wet_atten
);

In Parameters

S
indicates the sample handle whose distances are to be set.
max_dist
is the distance at which the sound will be clipped to silence. Note that this parameter does not affect the volume falloff curve.
min_dist
is the distance at which the sound will be at maximum volume. That is, any sound that is this distance or closer to the listener will be at maximum volume.
auto_3D_wet_atten
determines whether environmental reverb effects on this HSAMPLE will be attenuated along with the HSAMPLE itself as the source recedes from the listener's location. Most applications should set this parameter to a nonzero value to enable automatic attenuation of the wet mix.

Discussion

Since sound effects should always be normalized to use the maximum resolution of the sound's bit depth (8-bit or 16-bit), you'll need to use the minimum and maximum sample distances to make each sound "feel correct" as it approaches and moves away from the listener.

For example, a bumblebee could have a minimum-distance characteristic of 0.25, and maximum distance of one meter. In contrast, a jet plane might have a minimum distance of a hundred meters (where it's loudest) and a maximum distance of two thousand meters (where it's clipped to silence).

You can override the system's default 3D-distance attenuation behavior by registering a custom falloff function with AIL_register_falloff_function_callback. By default, as a sound approaches the listener, each time the distance between the listener and the sound is halved, the volume of the sound is doubled. This means that any sound at the maximum distance or greater from the listener is silent, any sound within the minimum distance is the maximum volume, and in between the minimum and maximum distances, the volume is set to one half as loud each time the distance from the listener to the minimum distance is doubled.

Another way to look at it is that if your minimum distance was 1, then at 2 your volume would be 50%, at 4 your volume would be 25%, at 8 your volume would be 12.5%, etc. Basically, just remember that it is not a linear falloff!

This is why you can't use zero for the minimum distance with the default MSS falloff-calculation mechanism in place - the sound volume would fall off infinitely fast and you'd never hear anything.

Note that the maximum distance doesn't affect the volume falloff curve! The maximum distance just establishes a hard clip point where the volume is forced to zero.

Also note that some DirectSound drivers don't implement the maximum distance correctly with the DSBCAPS_MUTE3DATMAXDISTANCE flag. At the maximum distance on these drivers, the volume doesn't drop to zero -- instead, it just stops falling off.

Example files that use this function: examms.cpp

Group: Digital Audio Services
Related Functions: AILFALLOFFCB, AIL_active_sample_count, AIL_calculate_3D_channel_levels, AIL_register_falloff_function_callback, AIL_sample_3D_distances, AIL_set_3D_distance_factor, AIL_set_3D_rolloff_factor, AIL_set_sample_3D_cone, AIL_set_sample_3D_position
Related Basic Types: F32, HSAMPLE, MILES_OPEN_DIGITAL_FLAGS, S32, void
Related FAQs: How do I play a 3D digital sound?, How do I use multi-channel sound output in Miles?, My 3D sound isn't falling off like I expected - what's going on?, What's the best way to port my older Miles application to MSS 7?


AIL_sample_3D_distances

The function AIL_sample_3D_distances returns the current minimum and maximum distances for the specified sample handle.

void AIL_sample_3D_distances(
  HSAMPLE S,
  F32 *max_dist,
  F32 *min_dist,
  S32 *auto_3D_wet_atten
);

In Parameters

S
indicates the sample handle to query.

Out Parameters

max_dist
returns the current maximum front distance setting.
min_dist
returns the current minimum front distance setting.
auto_3D_wet_atten
returns whether or not environmental reverb effects on this HSAMPLE will be attenuated along with the HSAMPLE itself as the source recedes from the listener's location.

Discussion

You can pass NULL for any value that you're not interested in.

Group: Digital Audio Services
Related Functions: AIL_active_sample_count, AIL_register_falloff_function_callback, AIL_sample_3D_cone, AIL_set_sample_3D_distances
Related Basic Types: F32, HSAMPLE, S32, void
Related FAQs: My 3D sound isn't falling off like I expected - what's going on?


AIL_set_sample_3D_cone

The function AIL_set_sample_3D_cone sets the sound emission cone on a sample.

void AIL_set_sample_3D_cone(
  HSAMPLE S,
  F32 inner_angle,
  F32 outer_angle,
  F32 outer_volume
);

In Parameters

S
indicates the sample handle to control.
inner_angle
is the inner angle of the sound cone in degrees (0 to 360). If the listener is within this angle of this sample, then the sound is at its normal volume (based on its initial volume, distance, occlusion, etc).
outer_angle
is the outer angle of the sound cone in degrees (0 to 360). If the listener is outside the inner angle but still inside the outer angle, then the volume is scaled linearly from no scaling (when close to the inner angle) to the outer volume scale (when close or greater than the outer angle).
outer_volume
is the amount to scale the normal volume to when outside the outer angle. A value of 0 means the normal volume is scaled all the way to zero. A volume of 1.0 means that the normal volume isn't scaled at all (and you wouldn't hear the difference when inside or outside of the cone).

Discussion

By default, every sound is omni-directional - the inner and outer angles are 360 degrees and the outer volume is 1.0.

The inner angle should always be smaller than the outer angle.

Example files that use this function: examms.cpp

Group: Digital Audio Services
Related Functions: AIL_calculate_3D_channel_levels, AIL_sample_3D_cone, AIL_set_sample_3D_distances, AIL_set_sample_3D_position
Related Basic Types: F32, HSAMPLE, void
Related FAQs: How do I use multi-channel sound output in Miles?


AIL_sample_3D_cone

The function AIL_sample_3D_cone retrieves the current sound emission cone of a sample.

void AIL_sample_3D_cone(
  HSAMPLE S,
  F32 *inner_angle,
  F32 *outer_angle,
  F32 *outer_volume
);

In Parameters

S
indicates the sample handle to query.

Out Parameters

inner_angle
returns the inner angle of the sound cone in degrees (0 to 360). If the listener is within this angle of this sample, then the sound is at its normal volume (based on the initial volume, distance, occlusion, etc).
outer_angle
returns the outer angle of the sound cone in degrees (0 to 360). If the listener is outside the inner angle but still inside the outer angle, then the volume is scaled linearly from no scaling (when close to the inner angle) to the outer volume scale (when close or greater than the outer angle).
outer_volume
returns the amount to scale the normal volume to when outside the outer angle. A value of 0 means the normal volume is scaled all the way to zero. A volume of 1.0 means that the normal volume isn't scaled at all (and you wouldn't hear the difference when inside or outside of the cone).

Discussion

You can pass in NULL for any parameter that you aren't interested in.

By default, every sound is omni-directional - the inner and outer angles are 360 degrees and the outer volume is 1.0.

The inner angle is always smaller than the outer angle.

Example files that use this function: examms.cpp

Group: Digital Audio Services
Related Functions: AIL_sample_3D_distances, AIL_set_sample_3D_cone
Related Basic Types: F32, HSAMPLE, void


AIL_set_sample_occlusion

The function AIL_set_sample_occlusion sets the occlusion for the specified 3D sample.

void AIL_set_sample_occlusion(
  HSAMPLE S,
  F32 occlusion
);

In Parameters

S
indicates the sample handle to control.
occlusion
is the amount that the sample is occluded. This is a linear floating point value from completely non-occluded (0.0) to completely occluded (1.0).

Discussion

Occlusion means the sound is completely blocked - a sound playing in another room separated by a wall, for example.

By default, samples are completely non-occluded.

On most providers, occlusions are emulated with volume control. On the Miles Fast 2D, Dolby Surround, DTS, and EAX 2/3/4 providers, however, occlusions are performed in with a low-pass filter and sound really cool (they aren't completely linear across the frequency scale - you can still faintly hear low-frequency sounds - just like the guy with the stereo upstairs).

Example files that use this function: examms.cpp

Group: Digital Audio Services
Related Sections: Creative's EAX 2 Properties
Related Functions: AIL_sample_occlusion, AIL_set_sample_exclusion, AIL_set_sample_obstruction
Related Basic Types: F32, HSAMPLE, void
Related FAQs: How do I apply a low-pass filter?, What's the best way to port my older Miles application to MSS 7?


AIL_sample_occlusion

The function AIL_sample_occlusion retrieves the current occlusion level of the given sample.

F32 AIL_sample_occlusion(
  HSAMPLE S
);

In Parameters

S
indicates the sample handle to query.

Discussion

Occlusion means the sound is completely blocked - a sound playing in another room separated by a wall, for example.

By default, samples are completely non-occluded.

Occlusions are implemented with a low-pass filter function and sound really cool (they aren't completely linear across the frequency scale.... with most providers, you can still faintly hear low-frequency sounds, like the guy with the stereo upstairs).

Example files that use this function: examms.cpp

Group: Digital Audio Services
Related Functions: AIL_sample_exclusion, AIL_sample_obstruction, AIL_set_sample_occlusion
Related Basic Types: F32, HSAMPLE
Related FAQs: What's the best way to port my older Miles application to MSS 7?


AIL_set_sample_obstruction

The function AIL_set_sample_obstruction sets the obstruction for the specified 3D sample.

void AIL_set_sample_obstruction(
  HSAMPLE S,
  F32 obstruction
);

In Parameters

S
indicates the sample handle to control.
obstruction
is the amount that the sample is obstructed. This is a linear value from completely non-obstructed (0.0) to completely obstructed (1.0).

Discussion

Obstructions mean that the direct path of the sound is blocked, but an indirect path is still available - a sound playing from behind a crate, for example.

By default, samples are completely non-obstructed.

With most output options, obstructions are emulated with volume control. On the EAX 2/3/4 providers, however, obstructions are performed in hardware and sound really cool (you can still hear reflections because they bounce around the obstruction).

Example files that use this function: examms.cpp

Group: Digital Audio Services
Related Sections: Creative's EAX 2 Properties
Related Functions: AIL_sample_obstruction, AIL_set_sample_exclusion, AIL_set_sample_occlusion
Related Basic Types: F32, HSAMPLE, void
Related FAQs: What's the best way to port my older Miles application to MSS 7?


AIL_sample_obstruction

The function AIL_sample_obstruction retrieves the current obstruction level of the given sample.

F32 AIL_sample_obstruction(
  HSAMPLE S
);

In Parameters

S
indicates the sample handle to query.

Discussion

Obstructions mean that the direct path of the sound is blocked, but an indirect path is still available - a sound playing from behind a crate, for example.

By default, samples are completely non-obstructed.

Example files that use this function: examms.cpp

Group: Digital Audio Services
Related Functions: AIL_sample_exclusion, AIL_sample_occlusion, AIL_set_sample_obstruction
Related Basic Types: F32, HSAMPLE
Related FAQs: What's the best way to port my older Miles application to MSS 7?


AIL_set_sample_exclusion

The function AIL_set_sample_exclusion sets the exclusion for the specified 3D sample.

void AIL_set_sample_exclusion(
  HSAMPLE S,
  F32 obstruction
);

In Parameters

S
indicates the sample handle to control.
obstruction
is the amount that the sample is excluded. This is a linear value from completely non-excluded (0.0) to completely excluded (1.0).

Discussion

Exclusion means that the direct path of the sound is available, but the reverbations will be blocked - a sound playing outside a room, but through an open window, for example.

By default, samples are completely non-excluded.

On most providers, exclusions are emulated with the effects level control. On the EAX 3/4 providers, however, exclusions are performed in hardware and sound really nice.

Group: Digital Audio Services
Related Sections: Creative's EAX 3 Properties
Related Functions: AIL_sample_exclusion, AIL_set_sample_obstruction, AIL_set_sample_occlusion
Related Basic Types: F32, HSAMPLE, void
Related FAQs: What's the best way to port my older Miles application to MSS 7?


AIL_sample_exclusion

The function AIL_sample_exclusion retrieves the current exclusion level of the given sample.

F32 AIL_sample_exclusion(
  HSAMPLE S
);

In Parameters

S
indicates the sample handle to query.

Discussion

Exclusion means that the direct path of the sound is available, but the reverbations will be blocked - a sound playing outside a room, but through an open window, for example.

By default, samples are completely non-excluded.

On most providers, exclusions are emulated with the effects level control. On the EAX 3/4 provider, however, exclusions are performed in hardware and sound really nice.

Group: Digital Audio Services
Related Functions: AIL_sample_obstruction, AIL_sample_occlusion, AIL_set_sample_exclusion
Related Basic Types: F32, HSAMPLE
Related FAQs: What's the best way to port my older Miles application to MSS 7?


AIL_set_listener_3D_position

The function AIL_set_listener_3D_position sets the three-dimensional position of the 3D listener.

void AIL_set_listener_3D_position(
  HDIGDRIVER dig,
  F32 X,
  F32 Y,
  F32 Z
);

In Parameters

dig
indicates the driver representing the 3D listener.
X
specifies the X coordinate (usually imagined as left to right - left is negative, right is positive).
Y
specifies the Y coordinate (usually imagined as down to up - down is negative, up is positive).
Z
specifies the Z coordinate (usually imagined as back to front - back is negative, front is positive).

Discussion

Following DirectSound3D's somewhat-awkward lead, Miles uses the left-handed coordinate system. All of DirectX also uses left-handed coordinates, so passing in coordinates from a DirectX application is simple. OpenGL, on the other hand, cleanly uses right-handed coordinates, so you must invert the sign of the Z parameter before passing it into Miles.

Example files that use this function: examms.cpp

Group: Digital Audio Services
Related Functions: AIL_listener_3D_position, AIL_set_listener_3D_orientation, AIL_set_listener_3D_velocity, AIL_set_listener_3D_velocity_vector, AIL_set_sample_3D_position, AIL_update_listener_3D_position
Related Basic Types: F32, HDIGDRIVER, void
Related FAQs: How do I play a 3D digital sound?, How do I use multi-channel sound output in Miles?, What's the best way to port my older Miles application to MSS 7?


AIL_listener_3D_position

The function AIL_listener_3D_position retrieves the current 3D position of the 3D listener.

void AIL_listener_3D_position(
  HDIGDRIVER dig,
  F32 *X,
  F32 *Y,
  F32 *Z
);

In Parameters

dig
indicates the driver representing the 3D listener.

Out Parameters

X
returns the X coordinate.
Y
returns the Y coordinate.
Z
returns the Z coordinate.

Discussion

You can pass NULL for any value that you're not interested in.

Group: Digital Audio Services
Related Functions: AIL_set_listener_3D_position
Related Basic Types: F32, HDIGDRIVER, void
Related FAQs: What's the best way to port my older Miles application to MSS 7?


AIL_set_listener_3D_velocity

The function AIL_set_listener_3D_velocity sets the current velocity of the 3D listener.

void AIL_set_listener_3D_velocity(
  HDIGDRIVER dig,
  F32 dX_per_ms,
  F32 dY_per_ms,
  F32 dZ_per_ms,
  F32 magnitude
);

In Parameters

dig
indicates the driver representing the 3D listener.
dX_per_ms
is the normalized delta in meters in the X coordinate per millisecond.
dY_per_ms
is the normalized delta in meters in the Y coordinate per millisecond.
dZ_per_ms
is the normalized delta in meters in the Z coordinate per millisecond.
magnitude
is the magnitude of the delta X, delta Y, and delta Z vector.

Discussion

The velocity of a 3D object is used for calculating the Doppler pitch shift as well as the amount to move the object when Miles repositions the object with AIL_update_listener_3D_position.

Note that since the units for velocity are in meters per millisecond, the values passed to this function are generally very small. For example, at 20 miles an hour (about the fastest a human can run), you would be passing in roughly 0.009 for a non-normalized delta value.

Following DirectSound3D's somewhat-awkward lead, Miles uses the left-handed coordinate system. All of DirectX also uses left-handed coordinates, so passing in coordinates from a DirectX application is simple. OpenGL, on the other hand, cleanly uses right-handed coordinates, so you must invert the sign of the Z parameter before passing it into Miles.

Group: Digital Audio Services
Related Functions: AIL_listener_3D_velocity, AIL_set_3D_doppler_factor, AIL_set_listener_3D_orientation, AIL_set_listener_3D_position, AIL_set_listener_3D_velocity_vector, AIL_update_listener_3D_position
Related Basic Types: F32, HDIGDRIVER, void
Related FAQs: What's the best way to port my older Miles application to MSS 7?


AIL_listener_3D_velocity

The function AIL_listener_3D_velocity retrieves the current velocity of the 3D listener.

void AIL_listener_3D_velocity(
  HDIGDRIVER dig,
  F32 *dX_per_ms,
  F32 *dY_per_ms,
  F32 *dZ_per_ms
);

In Parameters

dig
indicates the driver representing the 3D listener.

Out Parameters

dX_per_ms
returns the current non-normalized delta value in meters per millisecond in the X dimension.
dY_per_ms
returns the current non-normalized delta value in meters per millisecond in the Y dimension.
dZ_per_ms
returns the current non-normalized delta value in meters per millisecond in the Z dimension.

Discussion

This function always returns non-normalized vectors.

You can pass NULL for any value that you're not interested in.

Group: Digital Audio Services
Related Functions: AIL_set_listener_3D_velocity, AIL_set_listener_3D_velocity_vector
Related Basic Types: F32, HDIGDRIVER, void
Related FAQs: What's the best way to port my older Miles application to MSS 7?


AIL_set_listener_3D_velocity_vector

The function AIL_set_listener_3D_velocity_vector sets the current velocity of the 3D listener.

void AIL_set_listener_3D_velocity_vector(
  HDIGDRIVER dig,
  F32 dX_per_ms,
  F32 dY_per_ms,
  F32 dZ_per_ms
);

In Parameters

dig
indicates the driver representing the 3D listener.
dX_per_ms
is the delta in meters in the X coordinate per millisecond.
dY_per_ms
is the delta in meters in the Y coordinate per millisecond.
dZ_per_ms
is the delta in meters in the Z coordinate per millisecond.

Discussion

The velocity of a 3D object is used for calculating the Doppler pitch shift, as well as the amount to move the object when Miles repositions the object with AIL_update_listener_3D_position.

Note that since the distances for velocity are in meters per millisecond, the values passed to this function are generally very small. For example, at 20 miles an hour (about the fastest a human can run), you would be passing in roughly 0.009 for a non-normalized delta value.

Following DirectSound3D's somewhat-awkward lead, Miles uses the left-handed coordinate system. All of DirectX also uses left-handed coordinates, so passing in coordinates from a DirectX application is simple. OpenGL, on the other hand, cleanly uses right-handed coordinates, so you must invert the sign of the Z parameter before passing it into Miles.

Group: Digital Audio Services
Related Functions: AIL_listener_3D_velocity, AIL_set_listener_3D_orientation, AIL_set_listener_3D_position, AIL_set_listener_3D_velocity, AIL_update_listener_3D_position
Related Basic Types: F32, HDIGDRIVER, void
Related FAQs: What's the best way to port my older Miles application to MSS 7?


AIL_update_listener_3D_position

The function AIL_update_listener_3D_position updates the 3D listener's position based on its previously set velocity and the specified delta time in milliseconds.

void AIL_update_listener_3D_position(
  HDIGDRIVER dig,
  F32 dt_milliseconds
);

In Parameters

dig
indicates the driver representing the 3D listener.
dt_milliseconds
indicates the amount of time that has passed in milliseconds.

Discussion

This function simply takes the current position and moves it based on the velocity vector and specified millisecond count.

Group: Digital Audio Services
Related Functions: AIL_set_listener_3D_position, AIL_set_listener_3D_velocity, AIL_set_listener_3D_velocity_vector
Related Basic Types: F32, HDIGDRIVER, void
Related FAQs: What's the best way to port my older Miles application to MSS 7?


AIL_set_listener_3D_orientation

The function AIL_set_listener_3D_orientation specifies the orientation of the 3D listener.

void AIL_set_listener_3D_orientation(
  HDIGDRIVER dig,
  F32 X_face,
  F32 Y_face,
  F32 Z_face,
  F32 X_up,
  F32 Y_up,
  F32 Z_up
);

In Parameters

dig
indicates the driver representing the 3D listener.
X_face
indicates the X coordinate of the facing vector.
Y_face
indicates the Y coordinate of the facing vector.
Z_face
indicates the Z coordinate of the facing vector.
X_up
indicates the X coordinate of the upward vector.
Y_up
indicates the Y coordinate of the upward vector.
Z_up
indicates the Z coordinate of the upward vector.

Discussion

Orientation is specified with two vectors. The facing vector tells which direction the object is facing (where the listener's 'nose' is pointing), and the upward vector is the vector pointing upward out of the top of the 3D object (out the top of the listener's head, for example).

The facing vector and upward vector should always be at right angles to each other. They will be normalized internally by MSS; you do not have to normalize them yourself.

Following DirectSound3D's somewhat-awkward lead, Miles uses the left-handed coordinate system. All of DirectX also uses left-handed coordinates, so passing in coordinates from a DirectX application is simple. OpenGL, on the other hand, cleanly uses right-handed coordinates, so you must invert the sign of the Z parameter before passing it into Miles.

Example files that use this function: examms.cpp

Group: Digital Audio Services
Related Functions: AIL_listener_3D_orientation, AIL_set_listener_3D_position, AIL_set_listener_3D_velocity, AIL_set_listener_3D_velocity_vector
Related Basic Types: F32, HDIGDRIVER, void
Related FAQs: What's the best way to port my older Miles application to MSS 7?


AIL_listener_3D_orientation

The function AIL_listener_3D_orientation retrieves the orientation of the 3D listener.

void AIL_listener_3D_orientation(
  HDIGDRIVER dig,
  F32 *X_face,
  F32 *Y_face,
  F32 *Z_face,
  F32 *X_up,
  F32 *Y_up,
  F32 *Z_up
);

In Parameters

dig
indicates the driver representing the 3D listener.

Out Parameters

X_face
returns the X coordinate of the facing vector.
Y_face
returns the Y coordinate of the facing vector.
Z_face
returns the Z coordinate of the facing vector.
X_up
returns the X coordinate of the upward vector.
Y_up
returns the Y coordinate of the upward vector.
Z_up
returns the Z coordinate of the upward vector.

Discussion

You can pass NULL for any value that you're not interested in.

Group: Digital Audio Services
Related Functions: AIL_set_listener_3D_orientation
Related Basic Types: F32, HDIGDRIVER, void
Related FAQs: What's the best way to port my older Miles application to MSS 7?


AIL_set_sample_3D_position

The function AIL_set_sample_3D_position sets a sample's current position in 3D space.

void AIL_set_sample_3D_position(
  HSAMPLE S,
  F32 X,
  F32 Y,
  F32 Z
);

In Parameters

S
specifies the 3D sample.
X
specifies the X coordinate (usually imagined as left to right - left is negative, right is positive).
Y
specifies the Y coordinate (usually imagined as down to up - down is negative, up is positive).
Z
specifies the Z coordinate (usually imagined as back to front - back is negative, front is positive).

Discussion

Assigning a 3D position to an HSAMPLE allows MSS to determine its channel levels automatically by performing distance and directionality calculations based on the relative positions of the HSAMPLE and its HDIGDRIVER (also known as the listener) in 3D space. Positions in 3D space are specified in left-handed coordinates (+X = right, +Y = up, +Z = front) by means of the AIL_set_sample_3D_position and AIL_set_listener_3D_position functions.

Even after you call AIL_set_sample_3D_position on an HSAMPLE, the sample's channel-level scale factors may still be specified by the application, if desired, with the AIL_set_sample_channel_levels function. The 3D positioner will continue to multiply its own set of scale factors with the default channel-level scalars until the HSAMPLE is released and reallocated, or reinitialized with a call to AIL_init_sample, AIL_set_sample_info, AIL_set_sample_file, or AIL_set_named_sample_file. Any of these actions will disable 3D positioning on an HSAMPLE when the MSS software mixer is in use.

Once an HSAMPLE has been placed under 3D control, a number of additional MSS API functions can be applied to the HSAMPLE. AIL_set_sample_3D_distances determines how distance-based attenuation is applied to the sound, while the AIL_set_sample_3D_cone and AIL_set_sample_3D_orientation functions give the sound a directional falloff characteristic. AIL_set_sample_3D_velocity applies Doppler shift to the sound. Similar functions apply to the listener object associated with the HDIGDRIVER. When the MSS software mixer is in use, none of the functions whose name contains '_3D_' affect HSAMPLES that have not been assigned a 3D position.

You should carefully review the How do I use multi-channel sound output in Miles? FAQ before using this function.

Example files that use this function: examms.cpp

Group: Digital Audio Services
Related Functions: AIL_calculate_3D_channel_levels, AIL_init_sample, AIL_sample_3D_position, AIL_sample_3D_velocity, AIL_set_listener_3D_position, AIL_set_named_sample_file, AIL_set_sample_3D_cone, AIL_set_sample_3D_distances, AIL_set_sample_3D_orientation, AIL_set_sample_3D_position, AIL_set_sample_3D_velocity, AIL_set_sample_3D_velocity_vector, AIL_set_sample_channel_levels, AIL_set_sample_file, AIL_set_sample_info, AIL_update_sample_3D_position
Related Basic Types: F32, HSAMPLE, MILES_OPEN_DIGITAL_FLAGS, void
Related FAQs: How do I play a 3D digital sound?, How do I use multi-channel sound output in Miles?, What's the best way to port my older Miles application to MSS 7?


AIL_sample_3D_position

The function AIL_sample_3D_position retrieves the current 3D position of a 3D sample.

S32 AIL_sample_3D_position(
  HSAMPLE S,
  F32 *X,
  F32 *Y,
  F32 *Z
);

In Parameters

S
specifies the 3D sample.

Out Parameters

X
returns the X coordinate.
Y
returns the Y coordinate.
Z
returns the Z coordinate.

Returns

Nonzero if the sample has been placed under 3D control by a call to AIL_set_sample_3D_position; zero if the sample is not subject to 3D positioning.

Discussion

You can pass NULL for any value that you're not interested in.

Group: Digital Audio Services
Related Functions: AIL_set_sample_3D_position
Related Basic Types: F32, HSAMPLE, S32
Related FAQs: How do I use multi-channel sound output in Miles?, What's the best way to port my older Miles application to MSS 7?


AIL_set_sample_3D_velocity

The function AIL_set_sample_3D_velocity sets the current velocity of a 3D sample.

void AIL_set_sample_3D_velocity(
  HSAMPLE S,
  F32 dX_per_ms,
  F32 dY_per_ms,
  F32 dZ_per_ms,
  F32 magnitude
);

In Parameters

S
specifies the 3D sample.
dX_per_ms
is the normalized delta in meters in the X coordinate per millisecond.
dY_per_ms
is the normalized delta in meters in the Y coordinate per millisecond.
dZ_per_ms
is the normalized delta in meters in the Z coordinate per millisecond.
magnitude
is the magnitude of the delta X, delta Y, and delta Z vector.

Discussion

The velocity of a 3D object is used for calculating the Doppler pitch shift, as well as the amount to move the object when Miles repositions the object with AIL_update_sample_3D_position.

Note that since the distances for velocity are in meters per millisecond, the values passed to this function are generally very small. For example, at 20 miles an hour (about the fastest a human can run), you would be passing in roughly 0.009 for a non-normalized delta value.

Following DirectSound3D's somewhat-awkward lead, Miles uses the left-handed coordinate system. All of DirectX also uses left-handed coordinates, so passing in coordinates from a DirectX application is simple. OpenGL, on the other hand, cleanly uses right-handed coordinates, so you must invert the sign of the Z parameter before passing it into Miles.

Group: Digital Audio Services
Related Functions: AIL_sample_3D_velocity, AIL_set_3D_doppler_factor, AIL_set_sample_3D_orientation, AIL_set_sample_3D_position, AIL_set_sample_3D_velocity_vector, AIL_update_sample_3D_position
Related Basic Types: F32, HSAMPLE, void
Related FAQs: How do I use multi-channel sound output in Miles?, What's the best way to port my older Miles application to MSS 7?


AIL_sample_3D_velocity

The function AIL_sample_3D_velocity retrieves the current velocity of a 3D sample.

void AIL_sample_3D_velocity(
  HSAMPLE S,
  F32 *dX_per_ms,
  F32 *dY_per_ms,
  F32 *dZ_per_ms
);

In Parameters

S
specifies the 3D sample.

Out Parameters

dX_per_ms
returns the current non-normalized delta value in meters per millisecond in the X dimension.
dY_per_ms
returns the current non-normalized delta value in meters per millisecond in the Y dimension.
dZ_per_ms
returns the current non-normalized delta value in meters per millisecond in the Z dimension.

Discussion

This function always returns non-normalized vectors.

You can pass NULL for any value that you're not interested in.

Group: Digital Audio Services
Related Functions: AIL_set_sample_3D_position, AIL_set_sample_3D_velocity, AIL_set_sample_3D_velocity_vector
Related Basic Types: F32, HSAMPLE, void
Related FAQs: What's the best way to port my older Miles application to MSS 7?


AIL_set_sample_3D_velocity_vector

The function AIL_set_sample_3D_velocity_vector sets the current velocity of a 3D sample.

void AIL_set_sample_3D_velocity_vector(
  HSAMPLE S,
  F32 dX_per_ms,
  F32 dY_per_ms,
  F32 dZ_per_ms
);

In Parameters

S
specifies the 3D sample.
dX_per_ms
is the delta in meters in the X coordinate per millisecond.
dY_per_ms
is the delta in meters in the Y coordinate per millisecond.
dZ_per_ms
is the delta in meters in the Z coordinate per millisecond.

Discussion

The velocity of a 3D object is used for calculating the Doppler pitch shift, as well as the amount to move the object when Miles repositions the object with AIL_update_sample_3D_position.

Note that since the distances for velocity are in meters per millisecond, the values passed to this function are generally very small. For example, at 20 miles an hour (about the fastest a human can run), you would be passing in roughly 0.009 for a non-normalized delta value.

Following DirectSound3D's somewhat-awkward lead, Miles uses the left-handed coordinate system. All of DirectX also uses left-handed coordinates, so passing in coordinates from a DirectX application is simple. OpenGL, on the other hand, cleanly uses right-handed coordinates, so you must invert the sign of the Z parameter before passing it into Miles.

Group: Digital Audio Services
Related Functions: AIL_sample_3D_velocity, AIL_set_sample_3D_orientation, AIL_set_sample_3D_position, AIL_set_sample_3D_velocity, AIL_update_sample_3D_position
Related Basic Types: F32, HSAMPLE, void
Related FAQs: What's the best way to port my older Miles application to MSS 7?


AIL_update_sample_3D_position

The function AIL_update_sample_3D_position updates a 3D sample's position based on its previously-set velocity and the specified delta time in milliseconds.

void AIL_update_sample_3D_position(
  HSAMPLE S,
  F32 dt_milliseconds
);

In Parameters

S
specifies the 3D sample.
dt_milliseconds
indicates the amount of time that has passed in milliseconds.

Discussion

This function simply takes the sample's current position and moves it based on the velocity vector and specified millisecond count.

Group: Digital Audio Services
Related Functions: AIL_set_sample_3D_position, AIL_set_sample_3D_velocity, AIL_set_sample_3D_velocity_vector
Related Basic Types: F32, HSAMPLE, void


AIL_set_sample_3D_orientation

The function AIL_set_sample_3D_orientation specifies the orientation of a 3D sample.

void AIL_set_sample_3D_orientation(
  HSAMPLE S,
  F32 X_face,
  F32 Y_face,
  F32 Z_face,
  F32 X_up,
  F32 Y_up,
  F32 Z_up
);

In Parameters

S
specifies the 3D sample.
X_face
indicates the X coordinate of the facing vector.
Y_face
indicates the Y coordinate of the facing vector.
Z_face
indicates the Z coordinate of the facing vector.
X_up
indicates the X coordinate of the upward vector.
Y_up
indicates the Y coordinate of the upward vector.
Z_up
indicates the Z coordinate of the upward vector.

Discussion

Orientation is specified with two vectors. The facing vector tells which direction the object is facing (where a character's nose is pointing, for instance), and the upward vector is the vector pointing upward out of the top of the 3D object (out the top of the character's head).

The facing vector and upward vector should always be at right angles to each other. They will be normalized internally by MSS; you do not need to normalize them yourself.

Following DirectSound3D's somewhat-awkward lead, Miles uses the left-handed coordinate system. All of DirectX also uses left-handed coordinates, so passing in coordinates from a DirectX application is simple. OpenGL, on the other hand, cleanly uses right-handed coordinates, so you must invert the sign of the Z parameter before passing it into Miles.

Example files that use this function: examms.cpp

Group: Digital Audio Services
Related Functions: AIL_sample_3D_orientation, AIL_set_sample_3D_position, AIL_set_sample_3D_velocity, AIL_set_sample_3D_velocity_vector
Related Basic Types: F32, HSAMPLE, void
Related FAQs: How do I use multi-channel sound output in Miles?, What's the best way to port my older Miles application to MSS 7?


AIL_sample_3D_orientation

The function AIL_sample_3D_orientation retrieves the orientation of a 3D sample.

void AIL_sample_3D_orientation(
  HSAMPLE S,
  F32 *X_face,
  F32 *Y_face,
  F32 *Z_face,
  F32 *X_up,
  F32 *Y_up,
  F32 *Z_up
);

In Parameters

S
specifies the 3D sample.

Out Parameters

X_face
returns the X coordinate of the facing vector.
Y_face
returns the Y coordinate of the facing vector.
Z_face
returns the Z coordinate of the facing vector.
X_up
returns the X coordinate of the upward vector.
Y_up
returns the Y coordinate of the upward vector.
Z_up
returns the Z coordinate of the upward vector.

Discussion

You can pass NULL for any value that you're not interested in.

Group: Digital Audio Services
Related Functions: AIL_set_sample_3D_orientation
Related Basic Types: F32, HSAMPLE, void
Related FAQs: What's the best way to port my older Miles application to MSS 7?


AIL_set_room_type

The function AIL_set_room_type sets the room type that the listener is currently in.

void AIL_set_room_type(
  HDIGDRIVER driver,
  S32 room_type
);

In Parameters

driver
indicates the driver representing the listener.
room_type
indicates the one of the MILES_ROOM_TYPE constants.

Discussion

Use ENVIRONMENT_GENERIC to use the provider's default settings. Use AIL_set_sample_reverb_levels to control the amount of room effects applied to each sample.

It's mandatory to use AIL_set_sample_reverb_levels to turn the wet effects level up for any 3D samples that should have reverb. The per-sample wet level defaults to 0.0, so if you're not hearing your selected room effects, this is probably why!

You can find out if the provider you are using supports room types by querying the current room type with AIL_room_type. If it returns a -1, then room-type control is unsupported.

This function will have no effect with per-voice hardware drivers that don't support reverb in hardware. Currently, this applies only to the MSS_MC_DIRECTSOUND3D value from the MSS_MC_SPEC list, since the EAX providers handle reverb directly and the software-mixing options emulate EAX.

Example files that use this function: examms.cpp

Group: Digital Audio Services
Related Sections: Creative's EAX 2 Properties
Related Functions: AIL_digital_master_reverb, AIL_digital_master_reverb_levels, AIL_output_filter_driver_property, AIL_room_type, AIL_set_digital_master_reverb, AIL_set_digital_master_reverb_levels, AIL_set_sample_reverb_levels
Related Basic Types: HDIGDRIVER, MILES_ROOM_TYPE, MSS_MC_SPEC, S32, void
Related FAQs: What's the best way to port my older Miles application to MSS 7?


AIL_room_type

The function AIL_room_type returns the current room type.

S32 AIL_room_type(
  HDIGDRIVER driver
);

In Parameters

driver
indicates the driver to query.

Returns

One of the MILES_ROOM_TYPE constants.

Discussion

If the provider doesn't support room types, this function will return -1.

Example files that use this function: examms.cpp

Group: Digital Audio Services
Related Functions: AIL_set_room_type
Related Basic Types: HDIGDRIVER, MILES_ROOM_TYPE, S32
Related FAQs: What's the best way to port my older Miles application to MSS 7?


AIL_set_3D_rolloff_factor

The function AIL_set_3D_rolloff_factor sets the driver's global 3D rolloff factor.

void AIL_set_3D_rolloff_factor(
  HDIGDRIVER dig,
  F32 factor
);

In Parameters

dig
indicates the driver to set.
factor
indicates new rolloff factor to use.

Discussion

The rolloff factor controls how fast 3D audio will fall off with distance. The default is 1.0, which implies no change to the "real-world" falloff speed. You can double the falloff rate by using 2.0, and you can turn off the falloff completely by using 0.0.

Use the AIL_set_sample_3D_distances function to control the falloff curve for each sample.

Group: Digital Audio Services
Related Functions: AILFALLOFFCB, AIL_3D_rolloff_factor, AIL_active_sample_count, AIL_calculate_3D_channel_levels, AIL_set_sample_3D_distances
Related Basic Types: F32, HDIGDRIVER, void
Related FAQs: What's the best way to port my older Miles application to MSS 7?


AIL_3D_rolloff_factor

The function AIL_3D_rolloff_factor returns the driver's current 3D rolloff factor.

F32 AIL_3D_rolloff_factor(
  HDIGDRIVER driver
);

In Parameters

driver
indicates the driver to query.

Returns

The drivers's current global rolloff factor.

Discussion

The default rolloff factor is 1.0, which implies no change to the "real-world" falloff speed.

Group: Digital Audio Services
Related Functions: AIL_set_3D_rolloff_factor
Related Basic Types: F32, HDIGDRIVER
Related FAQs: What's the best way to port my older Miles application to MSS 7?


AIL_set_3D_doppler_factor

The function AIL_set_3D_doppler_factor sets the driver's global 3D Doppler factor.

void AIL_set_3D_doppler_factor(
  HDIGDRIVER driver,
  F32 factor
);

In Parameters

driver
indicates the driver to set.
factor
indicates new Doppler factor to use.

Discussion

The Doppler factor controls the scale of the Doppler effects. The default Doppler scale is 1.0 which means no change to the calculated "real-world" Doppler effect. You can double the Doppler effect by using 2.0, and you can turn off Doppler completely by using 0.0.

Use the AIL_set_sample_3D_velocity and AIL_set_listener_3D_velocity functions to set the velocities of your samples and the listener.

Group: Digital Audio Services
Related Functions: AIL_3D_doppler_factor, AIL_set_3D_distance_factor, AIL_set_listener_3D_velocity, AIL_set_sample_3D_velocity
Related Basic Types: F32, HDIGDRIVER, void
Related FAQs: What's the best way to port my older Miles application to MSS 7?


AIL_3D_doppler_factor

The function AIL_3D_doppler_factor returns the driver's current 3D Doppler factor.

F32 AIL_3D_doppler_factor(
  HDIGDRIVER driver
);

In Parameters

driver
indicates the driver to query.

Returns

The drivers's current global Doppler factor.

Discussion

The default Doppler scale factor is 1.0, which implies no change to the calculated "real-world" Doppler effect.

Group: Digital Audio Services
Related Functions: AIL_set_3D_doppler_factor
Related Basic Types: F32, HDIGDRIVER
Related FAQs: What's the best way to port my older Miles application to MSS 7?


AIL_set_3D_distance_factor

The function AIL_set_3D_distance_factor sets the driver's global 3D distance factor.

void AIL_set_3D_distance_factor(
  HDIGDRIVER driver,
  F32 factor
);

In Parameters

driver
indicates the driver to set.
factor
indicates the new distance factor to use.

Discussion

Internally, the 3D units used in Miles are meters, but you can switch to your game's own units by using this function. For example, if your game's units were feet, then you would specify 0.3048 for the distance factor (1 foot = 0.3048 meters).

It's actually rare that you need to use this function, since the AIL_set_sample_3D_distances function acts as the distance scale. So, the only time the distance factor is really used is in the Doppler calculations.

Group: Digital Audio Services
Related Functions: AIL_3D_distance_factor, AIL_set_3D_doppler_factor, AIL_set_sample_3D_distances
Related Basic Types: F32, HDIGDRIVER, void
Related FAQs: What's the best way to port my older Miles application to MSS 7?


AIL_3D_distance_factor

The function AIL_3D_distance_factor returns the driver's current 3D distance factor.

F32 AIL_3D_distance_factor(
  HDIGDRIVER driver
);

In Parameters

driver
indicates the driver to query.

Returns

The drivers's current global distance factor.

Discussion

The default distance factor is 1.0, which means your distances are specified in meters.

Group: Digital Audio Services
Related Functions: AIL_set_3D_distance_factor
Related Basic Types: F32, HDIGDRIVER
Related FAQs: What's the best way to port my older Miles application to MSS 7?


AIL_set_sample_loop_count

The function AIL_set_sample_loop_count arranges for a sample to be restarted immediately upon completion, for a total of two or more iterations.

void AIL_set_sample_loop_count(
  HSAMPLE S,
  S32 loop_count
);

In Parameters

S
indicates the sample to loop.
loop_count
should be set to the desired number of iterations.

Discussion

A loop_count value of 1 results in a single iteration, with no looping. This is the default loop count value, as initialized by AIL_init_sample.

A loop_count value of 0 creates an infinite loop, which can be interrupted by calling AIL_stop_sample, AIL_end_sample, or by calling AIL_set_sample_loop_count to establish a different loop count.

loop_count values of 2 or more cause the sample to be played a total of 2 or more times. The current number of iterations remaining may be monitored with AIL_sample_loop_count.

To loop a low-level streaming ("double-buffered") sample, it is necessary to trap the end-of-file condition (zero bytes read) and seek back to the file's beginning to re-execute the read call. The AIL_set_sample_loop_count function is not applicable to low-level streaming samples, since it can be used only when the entire sample is resident in memory. If used, it will cause only the currently playing buffer to loop, which is not likely to be the desired result. For more information about low-level streaming, refer to the AIL_sample_buffer_available function description. Note that the high-level streaming API handles looping for you!

To loop a stream, you must use AIL_set_stream_loop_count rather than calling AIL_set_sample_loop_count on the stream's underlying HSAMPLE.

Example files that use this function: SSTEST.C, EXAMMS.CPP

Group: Digital Audio Services
Related Functions: AIL_end_sample, AIL_init_sample, AIL_sample_buffer_available, AIL_sample_loop_block, AIL_sample_loop_count, AIL_set_sample_loop_block, AIL_set_sample_loop_count, AIL_set_stream_loop_count, AIL_stop_sample
Related Basic Types: HSAMPLE, S32, void
Related FAQs: I'm getting a glitch when I loop an MP3 or ADPCM file - what can I do?, What MP3 encoder should I use?


AIL_sample_loop_count

The function AIL_sample_loop_count returns the number of loop iterations remaining for the given sample.

S32 AIL_sample_loop_count(
  HSAMPLE S
);

In Parameters

S
indicates the sample handle whose current loop count is to be returned.

Returns

The sample's current loop count. A value of 0 means that the sample is looping indefinitely, while a value of 1 means that the sample is on its last iteration, or is not looping at all.

Discussion

See AIL_set_sample_loop_count for more information.

Group: Digital Audio Services
Related Functions: AIL_sample_loop_block, AIL_set_sample_loop_count
Related Basic Types: HSAMPLE, S32


AIL_set_sample_loop_block

The function AIL_set_sample_loop_block arranges for a sub-block of a sample to be looped.

void AIL_set_sample_loop_block(
  HSAMPLE S,
  S32 loop_start_offset,
  S32 loop_end_offset
);

In Parameters

S
indicates the sample to loop.
loop_start_offset
should be set to the offset of where looping should begin. If the sample is compressed, this offset is specified in "compressed" bytes.
loop_end_offset
should be set to the offset of where looping should end. If the sample is compressed, this offset is specified in "compressed" bytes.

Discussion

By default, looping a sound will loop the entire buffer. This function allows you to loop a smaller sub-section of the buffer.

If the sample data is compressed, then the offsets passed to this function is in "compressed" bytes.

A value of zero for loop_start_offset indicates the beginning of the sample, and a value of -1 for loop_end_offset indicates the end of the sample, regardless of its actual length.

Any calls to AIL_set_sample_position, AIL_set_stream_position, or AIL_set_sample_loop_block with MP3 source data should specify offsets that lie on frame boundaries. This helps us avoid mistakenly interpreting intraframe data as a valid frame boundary. The loop boundaries displayed by the Miles Sound Player are suitable for passing directly to AIL_set_sample_position, AIL_set_stream_position, or AIL_set_sample_loop_block. Note that MSS considers offset 0 to be the first byte after any ID3v2 tag or other metadata at the beginning of an MP3 file! Frame offsets reported by other MP3 editors will most likely be relative to the beginning of the entire file, making them unsuitable for use with the Miles API.

To loop a stream, you must use AIL_set_stream_loop_block rather than calling AIL_set_sample_loop_block on the stream's underlying HSAMPLE.

Group: Digital Audio Services
Related Functions: AIL_sample_loop_block, AIL_set_sample_loop_block, AIL_set_sample_loop_count, AIL_set_sample_position, AIL_set_stream_loop_block, AIL_set_stream_position
Related Basic Types: HSAMPLE, S32, void
Related FAQs: I'm getting a glitch when I loop an MP3 or ADPCM file - what can I do?, What MP3 encoder should I use?


AIL_sample_loop_block

The function AIL_sample_loop_block returns the beginning and ending loop offsets previously passed to AIL_set_sample_loop_block.

S32 AIL_sample_loop_block(
  HSAMPLE S,
  S32 *loop_start_offset,
  S32 *loop_end_offset
);

In Parameters

S
indicates the sample handle whose loop block offsets are to be returned.

Out Parameters

loop_start_offset
returns the offset in the source data where looping will begin, in bytes.
loop_end_offset
returns the offset in the source data at the end of the loop, in bytes.

Returns

The original loop count passed to AIL_set_sample_loop_count, if any. This is not the same as the sample's current loop count as returned by AIL_sample_loop_count.

Discussion

See AIL_set_sample_loop_block for more information.

A value of zero for loop_start_offset indicates the beginning of the sample, and a value of -1 for loop_end_offset indicates the end of the sample, regardless of its actual length.

Group: Digital Audio Services
Related Functions: AIL_sample_loop_count, AIL_set_sample_loop_block, AIL_set_sample_loop_count
Related Basic Types: HSAMPLE, S32


AIL_set_sample_position

The function AIL_set_sample_position adjusts the playback position of a sample.

void AIL_set_sample_position(
  HSAMPLE S,
  U32 pos
);

In Parameters

S
indicates the sample whose position is to be adjusted.
pos
indicates the offset in bytes of the new playback position from the beginning of the sample. If the sample is compressed, this offset is specified in "compressed" bytes.

Discussion

By means of this function, it is possible to instantaneously change the location from which sample data is being played. The change will take effect as soon as the next block of audio data from the sample is merged into the hardware buffer.

If the sample data is compressed, then the offset passed to this function is in "compressed" bytes.

The granularity of the seek position that you specified is based on the size of a sample for uncompressed data, or the ADPCM block size for ADPCM data.

You can use the AIL_set_sample_ms_position function to set a new sample position based on milliseconds.

Not all compressed file types support seeking to arbitrarily-precise locations in MSS. If your application cannot tolerate approximations in seeking operations, it's best to stick with MP3 data and review the I'm getting a glitch when I loop an MP3 or ADPCM file - what can I do? FAQ carefully.)

Any calls to AIL_set_sample_position, AIL_set_stream_position, or AIL_set_sample_loop_block with MP3 source data should specify offsets that lie on frame boundaries. This helps us avoid mistakenly interpreting intraframe data as a valid frame boundary. The loop boundaries displayed by the Miles Sound Player are suitable for passing directly to AIL_set_sample_position, AIL_set_stream_position, or AIL_set_sample_loop_block. Note that MSS considers offset 0 to be the first byte after any ID3v2 tag or other metadata at the beginning of an MP3 file! Frame offsets reported by other MP3 editors will most likely be relative to the beginning of the entire file, making them unsuitable for use with the Miles API.

Group: Digital Audio Services
Related Functions: AIL_sample_granularity, AIL_sample_ms_position, AIL_sample_position, AIL_set_sample_loop_block, AIL_set_sample_ms_position, AIL_set_sample_position, AIL_set_stream_position, AIL_start_sample
Related Basic Types: HSAMPLE, U32, void
Related FAQs: I'm getting a glitch when I loop an MP3 or ADPCM file - what can I do?


AIL_sample_position

The function AIL_sample_position reports the current playback position of a sample.

U32 AIL_sample_position(
  HSAMPLE S
);

In Parameters

S
indicates the sample whose playback position is to be reported.

Returns

The offset in bytes of the next sample point to be fetched, relative to the beginning of the sample's data buffer.

Discussion

The granularity of the reported position offset depends on the hardware's buffer latency, but it will always reflect an address which has not yet been reached by the playback mechanism.

The Miles Sound System digital audio mixer operates on the application's audio data in small chunks, called blocks. Part of the system's responsibility is to poll the hardware buffers in the background to determine when the next block of audio data from the application should be processed and copied into an empty hardware half-buffer. As an example, consider a hardware driver which is configured to play 16-bit audio at 20,000 Hz with a pair of 1,000-byte half-buffers. The driver's data rate is 40,000 bytes per second, implying a half-buffer playback rate of 40,000 / 1,000, or 40 buffer transitions per second.

At a rate of 40 times per second, then, a sample block equivalent to one half-buffer's worth of data is fetched from the application's sample data buffer at the current playback position. The samples are resampled if necessary to conform to the driver's hardware rate, converted between 8-bit and 16-bit formats where appropriate, mathematically scaled for volume and panpot control, algebraically added to data from other active samples, clipped, and copied into the driver's empty half-buffer to be played as soon as the other half-buffer finishes playing.

AIL_sample_position reports the location of the beginning of the next application data block to be fetched and processed by this mechanism.

You can use the AIL_sample_ms_position function to retrieve the current sample position in milliseconds.

Group: Digital Audio Services
Related Functions: AIL_register_SOB_callback, AIL_sample_granularity, AIL_sample_ms_position, AIL_sample_position, AIL_set_sample_ms_position, AIL_set_sample_position
Related Basic Types: HSAMPLE, U32
Related FAQs: What's the best way to port my older Miles application to MSS 7?


AIL_set_sample_ms_position

The function AIL_set_sample_ms_position adjusts the playback position of a sample.

void AIL_set_sample_ms_position(
  HSAMPLE S,
  S32 milliseconds
);

In Parameters

S
indicates the sample whose position is to be adjusted.
milliseconds
indicates the millisecond count of the new playback position.

Discussion

This function simply converts the millisecond value to a sample position in bytes and then calls AIL_set_sample_position.

Group: Digital Audio Services
Related Functions: AIL_sample_ms_position, AIL_sample_position, AIL_set_sample_position
Related Basic Types: HSAMPLE, S32, void


AIL_sample_ms_position

The function AIL_sample_ms_position reports the current playback position and length of a sample in milliseconds.

void AIL_sample_ms_position(
  HSAMPLE S,
  S32 *total_milliseconds,
  S32 *current_milliseconds
);

In Parameters

S
indicates the sample whose playback position is to be reported.

Out Parameters

total_milliseconds
is the address to place the total length of the sample into. If you don't need the total length, pass a NULL for this parameter.
current_milliseconds
is the address to place the current millisecond position into. This value increases as the sample is played. If you don't need the current position, pass a NULL for this parameter.

Group: Digital Audio Services
Related Functions: AIL_sample_position, AIL_set_sample_ms_position, AIL_set_sample_position
Related Basic Types: HSAMPLE, S32, void
Related FAQs: This function returns a bunch of return data, but I only want one value - is there a simpler way to use it?


AIL_sample_status

The function AIL_sample_status returns the status of a given sample handle.

U32 AIL_sample_status(
  HSAMPLE S
);

In Parameters

S
indicates the sample handle for which the status is to be returned.

Returns

One of the MILES_DIGITAL_STATUS constants.

Discussion

For one way to use AIL_sample_status in a typical MSS application, see the AIL_allocate_sample_handle function description.

Example files that use this function: SSTEST.C

Group: Digital Audio Services
Related Functions: AIL_active_sample_count, AIL_allocate_sample_handle, AIL_end_sample, AIL_sample_status
Related Basic Types: HSAMPLE, MILES_DIGITAL_STATUS, U32
Related FAQs: When can I free the memory I gave to MSS?


MILES_DIGITAL_STATUS

The basic type MILES_DIGITAL_STATUS describes the current state of the digital audio.

Fundamental Values

Value | Description
SMP_DONE | Sample has finished playing, or has never been started. (Debugger value: 2).
SMP_PLAYING | Sample is currently playing (active). (Debugger value: 4).
SMP_STOPPED | Sample has been stopped/paused. (Debugger value: 8).
SMP_FREE | Sample has been freed back to the system. (Debugger value: 1).
SMP_PLAYINGBUTRELEASED | (Windows and MacOS only) Sample is currently playing (active), but the hardware digital handle was released by a call to AIL_digital_handle_release. When the digital handle is reacquired, the sample will begin playing again. (Debugger value: 16).

Group: Digital Audio Services
Related Functions: AIL_active_sample_count, AIL_allocate_sample_handle, AIL_digital_handle_release, AIL_end_sample, AIL_init_sample, AIL_sample_status, AIL_stop_sample, AIL_stream_status
Related FAQs: When can I free the memory I gave to MSS?


AIL_set_sample_user_data

The function AIL_set_sample_user_data sets a value for one of eight user data entries associated with each sample handle.

void AIL_set_sample_user_data(
  HSAMPLE S,
  U32 index,
  SINTa value
);

In Parameters

S
indicates the sample for which a user data entry value is to be set.
index
is a number from 0 to 7, indicating which user data entry is to be set.
value
is the user data value to set.

Discussion

Sample user data entries are provided to assist application programs in keeping track of its allocated sample handles. They are especially useful for communicating with callback functions to which only sample handles are passed, without resorting to the use of global variables.

The MSS system never alters or initializes user data values under any circumstances even when a sample handle is freed.

Group: Digital Audio Services
Related Functions: AIL_sample_user_data
Related Basic Types: HSAMPLE, SINTa, U32, void


AIL_sample_user_data

The function AIL_sample_user_data retrieves a value for one of eight user data entries associated with each sample handle.

SINTa AIL_sample_user_data(
  HSAMPLE S,
  U32 index
);

In Parameters

S
indicates the sample for which a user data entry value is to be retrieved.
index
is a number from 0 to 7, indicating which user data entry value is to be retrieved.

Returns

The value which was previously stored at user data entry index.

Discussion

Sample user data entries are provided to assist application programs in keeping track of its allocated sample handles. They are especially useful for communicating with callback functions to which only sample handles are passed, without resorting to the use of global variables.

The MSS system never alters or initializes user data values under any circumstances even when a sample handle is freed.

Group: Digital Audio Services
Related Functions: AIL_set_sample_user_data
Related Basic Types: HSAMPLE, SINTa, U32


AIL_minimum_sample_buffer_size

The function AIL_minimum_sample_buffer_size returns the minimum usable buffer size for use with the low-level streaming function AIL_load_sample_buffer.

S32 AIL_minimum_sample_buffer_size(
  HDIGDRIVER dig,
  S32 playback_rate,
  S32 format
);

In Parameters

dig
specifies which digital audio driver is to be used for low-level streaming audio playback.
playback_rate
specifies the intended playback rate in samples per second.
format
specifies the format of the audio data to be played. See AIL_init_sample for a description of the available audio formats.

Returns

The lowest usable size in bytes for each of the individual buffers used by the AIL_load_sample_buffer function.

Discussion

When playing uncompressed PCM data, MSS's built-in low-level streaming mechanism (namely, the AIL_sample_buffer_available and AIL_load_sample_buffer functions) cannot be used with buffers which are smaller than the hardware half-buffer size used at the hardware level, because the hardware buffer can be filled with sample data only at its beginning and half-buffer points. The AIL_minimum_sample_buffer_size function returns the smallest PCM buffer size which can be used with a given driver configuration.

The value returned by this function is a minimum value, which will typically range from 2K to 8K bytes. Use of smaller buffers is likely to cause audio dropouts. It is permissible, and often advisable, to use larger buffer sizes than that recommended by AIL_minimum_sample_buffer_size. For example, applications which are unable to poll the AIL_sample_buffer_available function frequently may need to employ buffer sizes of 16K, 32K, or greater.

In calculating the minimum usable buffer size, this function takes into account the difference between the driver's hardware playback rate and the sample's playback rate, as well as any conversions between 8-bit and 16-bit or mono and stereo formats that automatically occur during playback. Consequently, the value returned may be greater or less than the actual hardware half-buffer size. If the playback rate will be varied during the low-level streaming process, the highest rate to be used should be passed to AIL_minimum_sample_buffer_size so that the buffer size can accommodate variations at playback time.

Buffers which are smaller than the minimum size can be used under three conditions: (1) when the final fragment of sample data is being submitted; (2) when compressed data (.MP3, .OGG, etc.) is being played; and (3) when AIL_set_sample_buffer_count is used to make more than two low-level streaming buffers available for a given HSAMPLE. In general, as long as the mixer has enough data to avoid starvation in the interval(s) before the next time the buffers are serviced, dropouts will not occur.

Applications which play synchronized audio-video streams with small audio chunks (less than 4-8K) must be designed to queue video and/or audio frame data in memory, in order to present audio buffers of sufficient size to the low-level streaming playback routines.

Example files that use this function: DBTEST.C

Group: Digital Audio Services
Related Functions: AIL_init_sample, AIL_load_sample_buffer, AIL_minimum_sample_buffer_size, AIL_sample_buffer_available, AIL_sample_buffer_info, AIL_set_sample_buffer_count
Related Basic Types: HDIGDRIVER, S32


AIL_sample_buffer_available

The function AIL_sample_buffer_available checks to see if any of the buffers associated with a sample handle are ready to be filled with new audio data by the AIL_load_sample_buffer function.

S32 AIL_sample_buffer_available(
  HSAMPLE S
);

In Parameters

S
indicates the sample handle to check.

Returns

Zero if none of the sample's low-level streaming buffers require service, or nonzero if additional audio data can be submitted.

Discussion

There are three ways to play digital audio data with MSS. One method assumes that the entire audio sample to be played is resident in memory during playback. With this technique, the application calls AIL_set_sample_address to specify the location and size of the sample data, followed by a call to AIL_start_sample to begin playback of the audio data. Various functions such as AIL_set_sample_volume_pan and others allow the application to control various aspects of sample playback, before and during playback. The number of available sample handles determines how many independent samples may be played at once.

The second method is to simply use the high-level streaming services described in the "Digital Audio Streaming Services" chapter. These services allow you to stream or spool data off a hard drive or CD-ROM.

The final method, called low-level streaming, also allows full control over a sample's playback characteristics, and also permits as many samples to be played simultaneously as there are available handles. It differs from the first method in only one important way: the audio data to be played is passed to MSS in small, manageable chunks. With low-level streaming, the entire audio data sample does not need to fit into memory, so samples of any size can be played. The high-level streaming services were written using the low-level streaming calls, in fact.

First, two or more sound data buffers are allocated by the application from system memory. The application allocates a sample handle with AIL_allocate_sample_handle, initializes it with AIL_init_sample, and sets its playback rate with AIL_set_sample_playback_rate, exactly as would be done under the first method mentioned above. However, instead of using AIL_set_sample_address prior to the beginning of playback, an application which makes use of low-level streaming would open the file containing the desired sample data, and begin repeatedly executing a small loop of the form:

   while (AIL_sample_buffer_available(sample))
      {
      S32 len = read(file,buf[n],size);
      AIL_load_sample_buffer(sample,
                             MSS_BUFFER_HEAD,
                             buf[n],
                             len);
      n = (n + 1) % 2;  // (2 sample buffers by default)
      if (len == 0)
         {
         break;
         }
      }
   AIL_start_sample(sample);

to begin transferring data from the file into the two buffers associated with each sample handle.

By default, all HSAMPLE handles are created with a ring of two buffer pointers. (Additional buffer pointers may be allocated through the use of the AIL_set_sample_buffer_count function.) Normally, the second sample buffer is disabled by AIL_init_sample; it cannot be accessed by the application except through the two API calls associated with low-level streaming, AIL_sample_buffer_available and AIL_load_sample_buffer. Low-level streaming mode is enabled automatically for a sample handle when either of these calls are used by the application, and it will remain in effect until the next AIL_init_sample call for that sample handle.

Assuming that the HSAMPLE has two buffer pointers, the first two calls to AIL_sample_buffer_available will return nonzero values to indicate that both buffers should be filled. Normally, this is done by calling AIL_load_sample_buffer with the constant MSS_BUFFER_HEAD, to place incoming data at the head of the buffer list. Once both buffers have been filled with sample data, subsequent calls to AIL_sample_buffer_available will return zero, meaning that neither buffer needs to be filled with audio data ("serviced") for the moment.

As soon as the first buffer finishes playing, MSS will immediately switch to the second buffer, whose contents have presumably been updated by the application since the last time it was played.

Low-level streaming playback stops when a function such as AIL_stop_sample or AIL_end_sample is used, or when a buffer of length 0 is reached (this occurs at end-of-file when read is used in the example above). From the foregoing discussion, it should be apparent that the application must check the buffers' status with AIL_sample_buffer_available frequently enough to avoid buffer "starvation", a condition in which playback stops because new data has not been provided in a timely fashion. In general, the application should call its serve_sample routine, or perform a similar action, at a rate of better than half of either buffer's playback period. The playback period in seconds for a given buffer is equal to the buffer's size in bytes divided by the playback rate in samples per second. This period must be further divided by the number of bytes per sample (4 for stereo 16-bit samples, 1 for mono 8-bit samples, and so forth).

At first glance, the loop above would seem an ideal candidate for an MSS background timer service client. Under Win32, Win64 and MacOS X, this would work fine, but it will stall timer services for the duration of the I/O routine. Worse, under DOS, the C read function must call DOS (and the DOS extender) to read audio data from the sample file. While it is theoretically possible to perform DOS file access from a timer-based interrupt handler, doing so requires techniques which are beyond the scope of this documentation or any MSS example program. These techniques may or may not be usable with certain DOS extenders, so any attempt at DOS access from a timer callback function is made entirely at the programmer's risk. Although it is customary that all of a sample's ring buffers be the same size, it is not mandatory. The buffers may be of different sizes if desired, and their sizes may be changed "on the fly." (This normally happens when the very last chunk of audio data is read from the sample file unless the sample file's size happens to be an integer multiple of the buffer size.) It is important that the size of each individual buffer (except the last) be equal to or larger than the value returned by the AIL_minimum_sample_buffer_size function, since the application's buffers cannot be smaller than the hardware-level buffers (see below).

Low-level streaming audio data is often stored in raw form, but formats such as Ogg Vorbis and MP3 are also usable, along with other compressed formats used for applications such as video playback and VoIP. .VOC or .WAV files may not be passed to the low-level streaming routines, unless the application itself assumes responsibility for seeking past the header and terminator blocks in these files. (.VOC or .WAV files may be converted to raw data with the Miles Sound Studio utility, or with the RAD Video Tools which are available at our website. The AIL_set_sample_file function may be helpful in parsing .VOC and .WAV files as well.)

It is possible to mix streamed samples and conventional memory-resident samples freely. However, it may not be advisable to play more than one streaming sample at once, because the system overhead required to continually stream data from two separate files may give rise to sound dropouts, depending on the data rates involved. Experimentation and careful testing are recommended in such cases.

To loop a low-level streaming sample, it is necessary to trap the end-of-file condition (zero bytes read) and seek back to the file's beginning to re-execute the read call. The AIL_set_sample_loop_count function is not applicable to streaming samples, since it can be used only when the entire sample is resident in memory. If used, it will cause only the currently playing buffer to loop, which is not likely to be the desired result.

On MacOS, you should use the system file-reading function, PBRead, which provides asynchronous data-reading functionality.

Beginning with MSS version 7, applications that use AIL_load_sample_buffer must call AIL_start_sample themselves. Low-level streaming samples are no longer started automatically as soon as the first buffer is loaded. It's not necessary to check the status of a low-level streaming sample before calling AIL_start_sample -- if it's already playing, the call will be ignored.

Most applications should use MSS's higher-level streaming functions instead -- they remove a lot of complexity from the picture! See the "Digital Audio Streaming Services" chapter for more information.

Example files that use this function: DBTEST.C

Group: Digital Audio Services
Related Functions: AIL_allocate_sample_handle, AIL_end_sample, AIL_init_sample, AIL_load_sample_buffer, AIL_minimum_sample_buffer_size, AIL_sample_buffer_available, AIL_sample_buffer_count, AIL_sample_buffer_info, AIL_set_sample_address, AIL_set_sample_buffer_count, AIL_set_sample_file, AIL_set_sample_loop_count, AIL_set_sample_playback_rate, AIL_set_sample_volume_pan, AIL_start_sample, AIL_stop_sample
Related Basic Types: HSAMPLE, S32


AIL_load_sample_buffer

The function AIL_load_sample_buffer sets the address and length for one of the low-level streaming buffers associated with a sample handle, enabling low-level streaming mode for that sample handle.

void AIL_load_sample_buffer(
  HSAMPLE S,
  S32 buff_num,
  void const * buffer,
  U32 len
);

In Parameters

S
indicates the sample handle whose buffer address and size is to be set.
buff_num
the index of the buffer to be filled. (Normally, this should be the token MSS_BUFFER_HEAD to place the data at the head of the buffer queue).
buffer
points to the (application-owned) data for the specified low-level streaming buffer.
len
specifies the size of the buffer in bytes.

Discussion

For a complete discussion of low-level streaming audio playback, including the use of the two API functions AIL_sample_buffer_available and AIL_load_sample_buffer, see the description of the AIL_sample_buffer_available function.

For higher-level streaming, read the "Digital Audio Streaming Services" chapter.

Example files that use this function: DBTEST.C

Group: Digital Audio Services
Related Functions: AIL_load_sample_buffer, AIL_minimum_sample_buffer_size, AIL_sample_buffer_available, AIL_sample_buffer_count, AIL_sample_buffer_info, AIL_set_sample_buffer_count, AIL_start_sample
Related Basic Types: HSAMPLE, S32, U32, void, void const *
Related FAQs: What's the best way to port my older Miles application to MSS 7?


AIL_sample_buffer_info

The function AIL_sample_buffer_info returns detailed information about the status of the low-level streaming buffers for the specified sound handle.

S32 AIL_sample_buffer_info(
  HSAMPLE S,
  S32 buff_num,
  U32 *pos,
  U32 *len,
  S32 *head,
  S32 *tail
);

In Parameters

S
indicates the sample handle to check.
buff_num
indicates the buffer to check, from 0 to the value returned by AIL_sample_buffer_count.

Out Parameters

pos
will receive the current position of buffer 0.
len
will receive the current size of buffer 0.
head
will receive the head index of the streaming buffer list (i.e., where audio data submitted to AIL_load_sample_buffer will be placed).
tail
will receive the tail index of the streaming buffer list (i.e., the buffer from which data is currently being fetched by the MSS mixer).

Returns

Whether the low-level streaming system has completely starved (all sound buffers have been exhausted).

Discussion

This function is rarely used - see AIL_sample_buffer_available for a more useful status function.

You will probably never need this function. It is needed primarily by video playback engines that need to monitor the low-level streaming state in minute detail.

Do NOT use this function to determine when to load another sample buffer - use the AIL_sample_buffer_available function instead.

Group: Digital Audio Services
Related Functions: AIL_load_sample_buffer, AIL_minimum_sample_buffer_size, AIL_sample_buffer_available
Related Basic Types: HSAMPLE, S32, U32


AIL_sample_buffer_count

The function AIL_sample_buffer_count returns the number of low-level streaming buffers associated with a sample.

S32 AIL_sample_buffer_count(
  HSAMPLE S
);

In Parameters

S
indicates the sample whose buffer count is to be returned.

Returns

The number of low-level streaming buffers associated with the HSAMPLE.

Discussion

All HSAMPLEs have at least 2 low-level streaming buffer pointers by default. Additional streaming buffer pointers may be allocated with AIL_set_sample_buffer_count.

Most applications should use high-level (HSTREAM) functions instead of low-level streaming.

Group: Digital Audio Services
Related Functions: AIL_load_sample_buffer, AIL_sample_buffer_available, AIL_set_sample_buffer_count
Related Basic Types: HSAMPLE, HSTREAM, S32


AIL_set_sample_buffer_count

The function AIL_set_sample_buffer_count sets the number of low-level streaming buffers available for use with a given sample handle.

S32 AIL_set_sample_buffer_count(
  HSAMPLE S,
  S32 n_buffers
);

In Parameters

S
indicates the sample for which the specified number of low-level streaming buffers are to be allocated.
n_buffers
indicates the number of desired low-level streaming buffers.

Returns

Nonzero if the allocation succeeded; 0 if the allocation failed.

Discussion

All HSAMPLEs have at least 2 low-level streaming buffer pointers by default. Additional streaming buffer pointers may be allocated with this function. (Note that these are only internal descriptors, not the buffers themselves. The actual data buffers used for low-level streaming are owned by the application.

Most applications should use high-level (HSTREAM) functions instead of low-level streaming.

Group: Digital Audio Services
Related Functions: AIL_load_sample_buffer, AIL_minimum_sample_buffer_size, AIL_sample_buffer_available, AIL_sample_buffer_count
Related Basic Types: HSAMPLE, HSTREAM, S32


AIL_sample_channel_count

The function AIL_sample_channel_count returns information about the source channels associated with a sample.

S32 AIL_sample_channel_count(
  HSAMPLE S,
  U32 *dwChannelMask
);

In Parameters

S
indicates the sample whose channel information is to be returned.

Out Parameters

dwChannelMask
if not NULL, receives the Microsoft WDM-compatible channel mask for the sample.

Returns

The number of source channels associated with the HSAMPLE.

Discussion

This function returns 1 for mono samples, 2 for stereo samples, or the actual number of channels in a multichannel .WAV or Ogg Vorbis sample.

For a detailed discussion of the dwChannelMask parameter, see the How do I use multi-channel sound output in Miles? FAQ

Group: Digital Audio Services
Related Basic Types: HSAMPLE, S32, U32
Related FAQs: How do I use multi-channel sound output in Miles?


AIL_sample_granularity

The function AIL_sample_granularity returns the granularity of a sample in bytes.

U32 AIL_sample_granularity(
  HSAMPLE S
);

In Parameters

S
indicates the sample whose granularity is to be returned.

Returns

1 for 8-bit mono, 2 for 8-bit stereo, 2 for 16-bit mono, 4 for 16-bit stereo, or the ADPCM block size.

Discussion

This is the size of a single sample, unless the sample is IMA ADPCM-compressed, in which case it would be the length of the ADPCM block in bytes.

Group: Digital Audio Services
Related Functions: AIL_sample_position, AIL_set_sample_position
Related Basic Types: HSAMPLE, U32


AIL_set_sample_adpcm_block_size

The function AIL_set_sample_adpcm_block_size sets the block size for the IMA ADPCM data.

void AIL_set_sample_adpcm_block_size(
  HSAMPLE S,
  U32 block_size
);

In Parameters

S
indicates the sample whose block size is to be set.
block_size
indicates the ADPCM block size.

Discussion

This function is used when playing raw IMA ADPCM data. The AIL_WAV_info function can return the block size, or it can be obtained from the "alignment" field of a WAVEFORMAT structure.

The ADPCM block size controls the sample granularity of ADPCM data.

Group: Digital Audio Services
Related Functions: AIL_WAV_info, AIL_set_sample_address
Related Basic Types: HSAMPLE, U32, void


AIL_digital_CPU_percent

The function AIL_digital_CPU_percent returns the percentage of total CPU being spent in the Miles digital processing loop.

S32 AIL_digital_CPU_percent(
  HDIGDRIVER dig
);

In Parameters

dig
indicates the driver that you want to profile.

Returns

Percentage from 0 to 100 of the CPU that was used by the specified digital driver since the last time you called AIL_digital_CPU_percent.

Discussion

This includes mixing, format conversion, on-the-fly decompression of formats such as IMA ADPCM or MPEG Layer 3, and filling of the system buffers. Note that the tasks profiled by this function may vary from platform to platform.

Note that AIL_digital_CPU_percent provides an indication of loading as if the machine had only a single CPU. That is, if it reports, say, 8%, then it used 8% of just one of the CPUs. This is different than the Windows Task Manager which divides the percentage used by the number of CPUs. So, if AIL_digital_CPU_percent reports 8%, then Task Manager will say 4% on a dual CPU or hyper-threaded machine.

Group: Digital Audio Services
Related Functions: AIL_digital_CPU_percent, AIL_quick_set_reverb_levels, AIL_sample_reverb_levels, AIL_set_sample_reverb_levels
Related Basic Types: HDIGDRIVER, S32
Related FAQs: How much CPU do the various filters use?


AIL_digital_latency

The function AIL_digital_latency returns the approximate latency of a sound if it were started immediately.

S32 AIL_digital_latency(
  HDIGDRIVER dig
);

In Parameters

dig
indicates the driver that you want to query.

Returns

Milliseconds until the sound should be heard by the end-user.

Discussion

Latency is a combination of the sound card, sound driver, sound technology (DirectSound, waveOut or hardware drivers). This function isn't guaranteed to be perfect, but it will be as accurate as possible.

This function will not return meaningful results if a per-voice output filter (DirectSound3D or EAX) option was chosen when the digital driver was opened.

Group: Digital Audio Services
Related Basic Types: HDIGDRIVER, S32
Related FAQs: How much latency does Miles have?


AIL_set_speaker_configuration

The function AIL_set_speaker_configuration establishes the listener-relative location of the speaker array, and the falloff power factor used for sample spatialization.

void AIL_set_speaker_configuration(
  HDIGDRIVER dig,
  MSSVECTOR3D const *array,
  S32 n_channels,
  F32 falloff_power
);

In Parameters

dig
indicates the HDIGDRIVER whose speaker configuration is to be set.
array
specifies an array of 3D unit vectors which point to the speakers corresponding to the logical channels in the current output configuration.
n_channels
specifies the number of speaker location entries actually submitted. This can be 0 if you only wish to set the falloff power.
falloff_power
specifies the falloff power factor to be used for sample positioning.

Discussion

When MSS opens an HDIGDRIVER in configurations other than DirectSound3D/EAX, it chooses a reasonable set of default positions for the speakers in the configuration. In most cases, the speakers with directional characteristics (i.e., other than the subwoofer/LFE channel) are arrayed at roughly-equal intervals around the unit circle. Sophisticated applications may wish to allow the user to alter MSS's speaker positions to match the positions of the actual speakers that surround the listener. You can call AIL_set_speaker_configuration to submit an array containing zero to n speaker locations, where n is the number of logical channels in the configuration as reported by AIL_speaker_configuration. The submitted speaker locations will replace the default locations chosen at driver initialization time.

You may also wish to specify a falloff power greater than 1.0 to exaggerate the movement of sounds between speakers. At 1.0, MSS's 3D pan function is constant in power. A sound will not appear to grow louder or software as it moves around the listener, providing it remains equidistant. Higher falloff powers can make games sound more 'interesting' due to increased apparent movement of sound sources... but this effect comes at the expense of level accuracy, as the sound will not tend to be as loud when it's positioned between speakers. The examms example program can help you judge the effect of different falloff powers.

You can use AIL_set_speaker_configuration to change the falloff power without supplying new speaker locations. To do this, simply pass 0 for n_channels and NULL for array.

This function will have no effect with per-voice hardware drivers that don't use the Miles software mixer. Currently, this applies only to the MSS_MC_DIRECTSOUND3D and MSS_MC_EAX? values from the MSS_MC_SPEC list, since these providers use DirectSound3D voices for output.

For a detailed understanding of speaker configurations, you should carefully review the How do I use multi-channel sound output in Miles? FAQ before attempting to use this function.

Group: Digital Audio Services
Related Functions: AIL_set_speaker_configuration, AIL_speaker_configuration
Related Basic Types: F32, HDIGDRIVER, MSS_MC_SPEC, S32, void
Related Structures: MSSVECTOR3D
Related FAQs: How do I use multi-channel sound output in Miles?


AIL_speaker_configuration

The function AIL_speaker_configuration returns an array of 3D vectors describing the listener-relative locations of the array of speakers associated with the current output format, plus some additional information about the format.

MSSVECTOR3D * AIL_speaker_configuration(
  HDIGDRIVER dig,
  S32 *n_physical_channels,
  S32 *n_logical_channels,
  F32 *falloff_power,
  MSS_MC_SPEC *channel_spec
);

In Parameters

dig
indicates the HDIGDRIVER whose configuration information is to be returned.

Out Parameters

n_physical_channels
specifies a pointer to a variable of type S32 which will receive the number of physical output channels. This may be less than the number of logical channels used elsewhere by MSS, in the case of a matrix provider such as Dolby or SRS that multiplexes several logical channels onto two physical channels. It will be zero if a per-voice output filter is in use.
n_logical_channels
specifies a pointer to a variable of type S32 which will receive the number of output channels the Miles mixer will write to. It will be zero if a per-voice output filter is in use.
falloff_power
specifies a pointer to a variable of type F32 which will receive the falloff power in use by the Miles mixer. This will not be meaningful if a per-voice output filter is in use.
channel_spec
specifies a pointer to a variable of type MSS_MC_SPEC which will receive the channel specification that was actually opened by AIL_open_digital_driver or AIL_quick_startup.

Returns

The array of n_logical_channels 3D vectors describing the listener-relative positions of the speakers associated with the current output format.

Discussion

This function lets you retrieve the configuration information resulting from the last successful call to AIL_open_digital_driver or AIL_quick_startup. If you pass MSS_MC_USE_SYSTEM_CONFIG to these functions, you can call AIL_speaker_configuration to discover what was actually chosen by the system.

MSS_MC_SPEC enum | Physical/logical channels | Logical SPEAKER_ array
MSS_MC_DIRECTSOUND3D | 0/0 | NA
MSS_MC_EAX2 | 0/0 | NA
MSS_MC_EAX3 | 0/0 | NA
MSS_MC_EAX4 | 0/0 | NA
MSS_MC_MONO | 1/1 | FL
MSS_MC_STEREO | 2/2 | FL,FR
MSS_MC_HEADPHONES | 2/2 | FL,FR
MSS_MC_40_DISCRETE | 4/4 | FL,FR,BL,BR
MSS_MC_DOLBY_SURROUND | 2/3 | FL,FR,BC
MSS_MC_SRS_CIRCLE_SURROUND | 2/7 | FL,FR,FC,LF,BL,BR,BC
MSS_MC_51_DISCRETE | 6/6 | FL,FR,FC,LF,BL,BR
MSS_MC_61_DISCRETE | 7/7 | FL,FR,FC,LF,BL,BR,BC
MSS_MC_71_DISCRETE | 8/8 | FL,FR,FC,LF,BL,BR,SL,SR
MSS_MC_81_DISCRETE | 9/9 | FL,FR,FC,LF,BL,BR,BC,SL,SR

You can obtain the number of physical and logical channels in use by calling AIL_speaker_configuration, as well as the MSS_MC_SPEC value passed to (or chosen by) AIL_open_digital_driver. As can be seen in the table above, these will be identical for all conventional (non-matrix) discrete formats, while matrix formats such as Dolby and SRS Circle Surround(r) can map three or more logical channels onto two physical channels. DirectSound3D and EAX will report zero physical channels and zero logical channels, since Windows insulates the application from these details.

For a detailed understanding of per-channel level control, you should carefully review the How do I use multi-channel sound output in Miles? FAQ before attempting to use this function.

Group: Digital Audio Services
Related Functions: AIL_calculate_3D_channel_levels, AIL_open_digital_driver, AIL_quick_startup, AIL_set_speaker_configuration, AIL_speaker_configuration
Related Basic Types: F32, HDIGDRIVER, MSS_MC_SPEC, S32
Related Structures: MSSVECTOR3D
Related FAQs: How do I use multi-channel sound output in Miles?


AIL_enumerate_output_filter_driver_properties

The function AIL_enumerate_output_filter_driver_properties enumerates the possible driver-level properties of an output filter.

S32 AIL_enumerate_output_filter_driver_properties(
  HPROVIDER filter,
  HINTENUM *next,
  RIB_INTERFACE_ENTRY *dest
);

In Parameters

filter
specifies the output filter whose driver-level properties should be enumerated.

Out Parameters

next
is a pointer that MSS uses to keep track of the next property to return. You initialize the next variable with the constant HINTENUM_FIRST before the first call to AIL_enumerate_output_filter_driver_properties.
dest
points to an structure of type RIB_INTERFACE_ENTRY that receives the property information. The most important field in this RIB structure is "entry_name" which is a pointer to the property name, which can then be used in the AIL_output_filter_driver_property function.

Returns

0 if no further properties were found; non-zero if another property was found.

Discussion

Certain digital sound configurations, including DirectSound3D, EAX, Dolby Surround, DTS, and SRS Circle Surround(r), are implemented with internal extension modules called output filters. Output filters can offer additional control options beyond those available from the core MSS API. Most applications will never need to work with output filter controls directly, but those that wish to do so can obtain a handle to the current voice or matrix output filter from AIL_digital_output_filter and access provider- and driver-level properties via the AIL_filter_property and AIL_output_filter_driver_property functions.

Sample-level properties may be accessed through calls to AIL_sample_stage_property with the SP_OUTPUT stage identifier. Sample-level property control is available only for hardware voice filters such as DirectSound3D and EAX, not matrix filters such as Dolby.

You can find a list of configuration-specific properties in chapter on the specific output filter you are using. See the examms demo program for an example of how to enumerate and query provider-level, driver-level, and sample-level properties.

Driver-level properties are properties that apply globally to a particular filter. For properties that are specific to each sample (sample-level properties) played by an output filter, use the AIL_enumerate_sample_stage_properties function with the SP_OUTPUT stage.

You can get the HPROVIDER handle corresponding to a driver's matrix or per-voice output filter, if any, by calling AIL_digital_output_filter.

Prior to MSS 7, 3D driver properties were accessed at the HPROVIDER level. In MSS 7, a given HPROVIDER may provide 3D services for a number of HDIGDRIVERS at once. Consequently, very few provider-level properties are associated with output filters other than the filter's name and version.

Example files that use this function: examms.cpp

Group: Digital Audio Services
Related Functions: AIL_digital_output_filter, AIL_enumerate_filter_properties, AIL_enumerate_output_filter_driver_properties, AIL_enumerate_sample_stage_properties, AIL_filter_property, AIL_output_filter_driver_property, AIL_sample_stage_property
Related Basic Types: HINTENUM, HPROVIDER, S32
Related Structures: RIB_INTERFACE_ENTRY


AIL_enumerate_output_filter_sample_properties

The function AIL_enumerate_output_filter_sample_properties enumerates the possible sample-level properties of an output filter.

S32 AIL_enumerate_output_filter_sample_properties(
  HPROVIDER filter,
  HINTENUM *next,
  RIB_INTERFACE_ENTRY *dest
);

In Parameters

filter
specifies the output filter whose sample-level properties should be enumerated.

Out Parameters

next
is a pointer that MSS uses to keep track of the next property to return. You initialize the next variable with the constant HINTENUM_FIRST before the first call to AIL_enumerate_output_filter_sample_properties.
dest
points to an structure of type RIB_INTERFACE_ENTRY that receives the property information. The most important field in this RIB structure is "entry_name". This is a pointer to the property name, which can be used in calls to the AIL_sample_stage_property function for the sample's SP_OUTPUT stage.

Returns

0 if no further properties were found; non-zero if another property was found.

Discussion

Certain digital sound configurations, including DirectSound3D, EAX, Dolby Surround, DTS, and SRS Circle Surround(r), are implemented with internal extension modules called output filters. Output filters can offer additional control options beyond those available from the core MSS API.

Sample-level properties are properties that apply to an individual HSAMPLE being processed or played by a particular filter.

Sample-level properties may be accessed through calls to AIL_sample_stage_property with the SP_OUTPUT stage identifier. Sample-level property control is available only for hardware voice filters such as DirectSound3D and EAX, not matrix filters such as Dolby.

You can find a list of configuration-specific properties in the chapter on the specific output filter you are using. See the examms demo program for an example of how to enumerate and query provider-level, driver-level, and sample-level properties.

You can get the HPROVIDER handle corresponding to a driver's matrix or per-voice output filter, if any, by calling AIL_digital_output_filter.

Prior to MSS 7, 3D driver properties were accessed at the HPROVIDER level. In MSS 7, a given HPROVIDER may provide 3D services for a number of HDIGDRIVERS at once. Consequently, very few provider-level properties are associated with output filters other than the filter's name and version.

You can also obtain a list of sample-specific output filter properties by calling the AIL_enumerate_sample_stage_properties function for the SP_OUTPUT stage of a given HSAMPLE. However, AIL_enumerate_output_filter_sample_properties works even without a valid HSAMPLE.

Example files that use this function: examms.cpp

Group: Digital Audio Services
Related Functions: AIL_digital_output_filter, AIL_enumerate_output_filter_sample_properties, AIL_enumerate_sample_stage_properties, AIL_output_filter_driver_property, AIL_sample_stage_property
Related Basic Types: HINTENUM, HPROVIDER, S32
Related Structures: RIB_INTERFACE_ENTRY


AIL_output_filter_driver_property

The function AIL_output_filter_driver_property retrieves and/or sets driver-level properties for an output filter.

S32 AIL_output_filter_driver_property(
  HDIGDRIVER dig,
  char const * property,
  void *before_value,
  void const * new_value,
  void *after_value
);

In Parameters

dig
indicates the driver whose installed output filter should be queried.
property
is a string variable describing the property to retrieve.
new_value
is a pointer to a new value to set. If you don't want to set the property, pass in 0.

Out Parameters

before_value
is a pointer to a variable that will contain the property value before changing it. Always use this pointer to retrieve read-only properties. You can use 0 if you don't want to retrieve the prior value.
after_value
is a pointer to a variable that will contain the property value after changing it. You can use 0 if you don't want to retrieve the post-value.

Returns

Non-zero for success, 0 for failure.

Discussion

Certain digital sound configurations, including DirectSound3D, EAX, Dolby Surround, DTS, and SRS Circle Surround(r), are implemented with internal extension modules called output filters. Output filters can offer additional control options beyond those available from the core MSS API. Most applications will never need to work with output filter controls directly, but those that wish to do so can obtain a handle to the current voice or matrix output filter from AIL_digital_output_filter and access provider- and driver-level properties via the AIL_filter_property and AIL_output_filter_driver_property functions.

You can find a list of configuration-specific properties in the chapter on the specific output filter you are using. See the examms demo program for an example of how to enumerate and query provider-level, driver-level, and sample-level properties.

Each per-voice output filter, such as those installed when MSS_MC_DIRECTSOUND3D or one of the EAX options is specified in a call to AIL_open_digital_driver, publishes a property called "Maximum supported samples" that returns the total number of 3D samples that can be (potentially) opened by that provider.

Many output filters also publish provider-specific properties -- see the provider information at the end of this chapter for details.

Retrieving Example: To obtain the total number of 3D samples that can be opened, you could use the following code:

U32 max_3D_samples;
AIL_output_filter_driver_property( opened_dig_driver,
                                   "Maximum supported samples",
                                   &max_3D_samples, 0, 0 );

Setting Example: To set the EAX room style, you could use the following code (you'd usually want to use the AIL_set_room_type function, though):

U32 room_style=EAX_ENVIRONMENT_BATHROOM;
AIL_output_filter_driver_property( eax_dig_driver,
                                  "EAX environment selection",
                                   0, &room_style, 0 );

(In reality, you still need to check the returned values from AIL_allocate_sample_handle, because not all of those hardware voices may be available by the time they're needed.)

Prior to MSS 7, 3D driver properties were accessed at the HPROVIDER level. In MSS 7, a given HPROVIDER may provide 3D services for a number of HDIGDRIVERS at once. Consequently, very few provider-level properties are associated with output filters other than the filter's name and version.

This function will have no effect if no per-voice or matrix output filter is in use.

Example files that use this function: examms.cpp

Group: Digital Audio Services
Related Sections: Creative's EAX 2 Properties, Creative's EAX 3 Properties, Creative's EAX 4 Properties
Related Functions: AIL_allocate_sample_handle, AIL_digital_output_filter, AIL_enumerate_output_filter_driver_properties, AIL_enumerate_output_filter_sample_properties, AIL_filter_property, AIL_open_digital_driver, AIL_output_filter_driver_property, AIL_set_room_type
Related Basic Types: HDIGDRIVER, S32, char const *, void, void const *
Related FAQs: What's the best way to port my older Miles application to MSS 7?


AIL_register_SOB_callback

The function AIL_register_SOB_callback arranges for callback service to be provided to an application's function just before a block of sample data is merged into the hardware buffer.

AILSAMPLECB AIL_register_SOB_callback(
  HSAMPLE S,
  AILSAMPLECB SOB
);

In Parameters

S
indicates the sample for which start-of-block (SOB) callback service is desired.
SOB
should be set to the address of the callback function which is to be invoked just before the audio data at AIL_sample_position is merged into the hardware buffer for playback. A value of NULL cancels start-of-block callbacks.

Returns

The address of the previously-installed SOB callback function handler.

Discussion

The Miles Sound System digital audio mixer operates on the application's audio data in small chunks, called blocks. Part of the system's responsibility is to poll the hardware buffers in the background to determine when the next block of audio data from the application should be processed and copied into an empty hardware half-buffer. As an example, consider a hardware driver which is configured to play 16-bit audio at 20,000 Hz with a pair of 1,000-byte half-buffers. The driver's data rate is 40,000 bytes per second, implying a half-buffer playback rate of 40,000 / 1,000, or 40 buffer transitions per second.

At a rate of 40 times per second, then, a sample block equivalent to one half-buffer's worth of data is fetched from the application's sample data buffer at the current playback position. The samples are resampled if necessary to conform to the driver's hardware rate, converted between 8-bit and 16-bit formats where appropriate, mathematically scaled for volume and panpot control, algebraically added to data from other active samples, clipped, and copied into the driver's empty half-buffer to be played as soon as the other half-buffer finishes playing.

Consequently, any change made to a sample's playback characteristics - be it a change in volume, panpot value, pitch, start/stop status, or playback position - must wait until the next half-buffer transition occurs before it can take effect. Certain applications, such as those employing synchronized video playback, may find it useful to set up a start-of-block callback handler with this function so they can be informed of exactly when their data is about to be processed. After the start-of-block callback occurs, the first data sample point at the current sample position (as reported by AIL_sample_position) is guaranteed to be transferred to the sound hardware in one half-buffer period or less. This period of "uncertainty" amounts to one to two half-buffer periods if the application merely relies on the time of its AIL_start_sample call to determine its audio playback timing, since a total of two hardware half-buffer transitions must occur before data from the sample is actually passed to the sound hardware.

Most MSS functions can be safely invoked from within callback functions. Exceptions include driver-installation or driver-shutdown functions and any other functions which may perform OS or BIOS calls, such as AIL_init_sequence. These exceptions are noted in the descriptions of the functions involved. If in doubt about whether a particular action may safely be performed from within a callback function, contact RAD Game Tools for assistance.

Under Win32 and Win64 on waveOut, the MSS architecture permits a sound effect to be started with essentially zero latency as long as no other sound effects are currently being played. On the other hand, latency times incurred for samples which must be injected into an already-running mixer stream may be much higher than even the worst figures obtained in the DOS version of MSS . Consequently, it is important when beginning video playback or any other latency-critical activity to ensure that no previous digital audio effects have been played for at least a few hundred milliseconds prior to starting playback of the critical sound effect or stream.

On a Win32 or Win64 system with a DirectSound driver installed, MSS will take advantage of the high-performance Microsoft DirectSound buffer mechanism to eliminate these latency problems.

Group: Digital Audio Services
Related Functions: AILSAMPLECB, AIL_init_sequence, AIL_register_EOB_callback, AIL_register_EOS_callback, AIL_sample_position, AIL_start_sample
Related Basic Types: HSAMPLE
Related FAQs: What's the deal with callbacks - are they threads, interrupts, system timers, or what?


AILSAMPLECB

The function AILSAMPLECB specifies a user-defined digital audio callback.

void AILCALLBACK AILSAMPLECB(
  HSAMPLE S
);

In Parameters

S
indicates the sample handle that generated the callback.

Discussion

This callback type can be made by several different digital audio events.

Group: Digital Audio Services
Related Functions: AIL_register_EOB_callback, AIL_register_EOS_callback, AIL_register_SOB_callback
Related Basic Types: HSAMPLE, void


AIL_register_EOB_callback

The function AIL_register_EOB_callback arranges for callback service to be provided to an application function immediately upon reaching the end of a sample buffer.

AILSAMPLECB AIL_register_EOB_callback(
  HSAMPLE S,
  AILSAMPLECB EOB
);

In Parameters

S
indicates the sample for which end-of-buffer (EOB) callback service is desired.
EOB
should be set to the address of the callback function which is to be invoked just after the last audio data block in a sample buffer is merged into the hardware buffer for playback. A value of NULL cancels end-of-block callbacks.

Returns

The address of the previously-installed EOB callback function handler.

Discussion

EOB callback functions perform essentially the same function as EOS (end-of-sample) callback functions when single-buffered samples are played. However, when using the low-level streaming functions, the EOB callback will be invoked at every application buffer transition, while EOS will be invoked only when an empty buffer is reached.

Most MSS functions can be safely invoked from within callback functions. Exceptions include driver-installation or driver-shutdown functions and any other functions which may perform OS or BIOS calls, such as AIL_init_sequence. These exceptions are noted in the descriptions of the functions involved. If in doubt about whether a particular action may safely be performed from within a callback function, contact RAD Game Tools for assistance.

Group: Digital Audio Services
Related Functions: AILSAMPLECB, AIL_init_sequence, AIL_register_EOS_callback, AIL_register_SOB_callback
Related Basic Types: HSAMPLE
Related FAQs: What's the deal with callbacks - are they threads, interrupts, system timers, or what?


AIL_register_EOS_callback

The function AIL_register_EOS_callback arranges for callback service to be provided to an application function immediately upon reaching the end of a sample.

AILSAMPLECB AIL_register_EOS_callback(
  HSAMPLE S,
  AILSAMPLECB EOS
);

In Parameters

S
indicates the sample for which end-of-sample (EOS) callback service is desired.
EOS
should be set to the address of the callback function which is to be invoked just after the last audio data block in a sample is merged into the hardware buffer for playback. A value of NULL cancels end-of-sample callbacks.

Returns

The address of the previously-installed EOS callback function handler.

Discussion

EOS callback functions perform essentially the same function as EOB (end-of-buffer) callback functions when single-buffered samples are played. However, when using the low-level streaming functions, the EOB callback will be invoked at every application buffer transition, while EOS will be invoked only when an empty buffer is reached.

Note that EOS callbacks may be invoked from within AIL_start_sample itself, if the amount of sample data is smaller than the internal buffer which MSS fills at sample startup time. Be sure to register your EOS callback before starting the sample.

Most MSS functions can be safely invoked from within callback functions. Exceptions include driver-installation or driver-shutdown functions and any other functions which may perform OS or BIOS calls, such as AIL_init_sequence. These exceptions are noted in the descriptions of the functions involved. If in doubt about whether a particular action may safely be performed from within a callback function, contact RAD Game Tools for assistance.

Group: Digital Audio Services
Related Functions: AILSAMPLECB, AIL_init_sequence, AIL_register_EOB_callback, AIL_register_SOB_callback, AIL_start_sample
Related Basic Types: HSAMPLE
Related FAQs: What's the deal with callbacks - are they threads, interrupts, system timers, or what?


AILFALLOFFCB

The function AILFALLOFFCB specifies a user-defined 3D distance-based falloff function callback.

F32 AILCALLBACK AILFALLOFFCB(
  HSAMPLE sample,
  F32 distance,
  F32 rolloff_factor,
  F32 min_distance,
  F32 max_distance
);

In Parameters

sample
indicates the HSAMPLE for which the callback is being issued.
distance
indicates the distance (in user units) between the emitter and listener.
rolloff_factor
indicates the rolloff factor. This value defaults to 1.0, but can be altered by calling AIL_set_3D_rolloff_factor.
min_distance
indicates the sample's minimum distance, as defined by the most recent call to AIL_set_sample_3D_distances.
max_distance
indicates the sample's maximum distance, as defined by the most recent call to AIL_set_sample_3D_distances.

Returns

This callback should return a value from 0.0 to 1.0, which will be treated as a linear amplitude scalar during the system's internal volume calculations. The equivalent gain in dB will be 20 * log10 (value) -- for example, a 6-dB power attenuation value would correspond to a returned value of 0.5.

Discussion

Note that falloff-function callbacks are invoked during background HSAMPLE processing. You should be careful not to make any API calls from within a falloff-function callback that could affect the state of the HSAMPLE or its corresponding HDIGDRIVER. If you do anything other than basic 3D state queries, undefined behavior may result. If in doubt about whether a particular action may safely be performed from within a falloff-function callback, contact RAD Game Tools for assistance.

Group: Digital Audio Services
Related Functions: AIL_register_falloff_function_callback, AIL_set_3D_rolloff_factor, AIL_set_sample_3D_distances
Related Basic Types: F32, HSAMPLE


AIL_register_falloff_function_callback

The function AIL_register_falloff_function_callback allows an application to override the system's default distance-based attenuation calculations for 3D-enabled samples.

AILFALLOFFCB AIL_register_falloff_function_callback(
  HSAMPLE S,
  AILFALLOFFCB falloff_function
);

In Parameters

S
indicates the sample for which the 3D falloff-function handler is to be installed.
falloff_function
should be set to the address of a user callback function which calculates the distance-based attenuation scalar for an HSAMPLE. A value of NULL restores the system's default (DirectSound3D-style) distance-calculation behavior.

Returns

The address of the previously-installed falloff-function handler (which may be a function internal to MSS if no previous user callback has been registered).

Discussion

When calculating how much to attenuate the volume of a 3D-enabled HSAMPLE based on its distance from the listener, the Miles Sound System normally uses an algorithm similar to the one that DirectSound3D and other standard 3D-sound APIs have traditionally employed. Specifically, the HSAMPLE's level is reduced by a linear scale factor of 0.5 (6 dB) for each doubling of the distance between the emitter and the listener's minimum-distance boundary. The default MSS falloff-function handler looks like this:

   F32 AILCALLBACK default_falloff_function (HSAMPLE   S,
                                             F32       distance,
                                             F32       rolloff_factor,
                                             F32       min_dist,
                                             F32       max_dist)
   {
      return min_dist / (min_dist + (rolloff_factor * (distance - min_dist)));
   }

It's important to note that user falloff functions have no effect on 3D-hardware processed HSAMPLEs. These include HSAMPLEs played through EAX/DirectSound3D providers, as well as HSAMPLEs played on the original Xbox when the driver has been opened with the AIL_OPEN_DIGITAL_NEED_HW_3D, AIL_OPEN_DIGITAL_NEED_FULL_3D, or AIL_OPEN_DIGITAL_NEED_LIGHT_3D flags.

Note that falloff-function callbacks are invoked during background HSAMPLE processing. You should be careful not to make any API calls from within a falloff-function callback that could affect the state of the HSAMPLE or its corresponding HDIGDRIVER. If you do anything other than basic 3D state queries, undefined behavior may result. If in doubt about whether a particular action may safely be performed from within a falloff-function callback, contact RAD Game Tools for assistance.

Group: Digital Audio Services
Related Functions: AILFALLOFFCB, AIL_sample_3D_distances, AIL_set_sample_3D_distances
Related Basic Types: HSAMPLE
Related FAQs: What's the deal with callbacks - are they threads, interrupts, system timers, or what?


AIL_active_sample_count

The function AIL_active_sample_count returns the number of currently-playing samples.

S32 AIL_active_sample_count(
  HDIGDRIVER dig
);

In Parameters

dig
specifies the digital audio driver whose active sample count is to be returned to the application.

Returns

The number of allocated sample handles whose status is SMP_PLAYING.

Discussion

This function provides a convenient alternative to calling AIL_sample_status from within a loop to determine if any samples are currently playing.

Example files that use this function: DIGPLAY.C

Group: Digital Audio Services
Related Functions: AIL_sample_3D_distances, AIL_sample_status, AIL_set_3D_rolloff_factor, AIL_set_sample_3D_distances
Related Basic Types: HDIGDRIVER, MILES_DIGITAL_STATUS, S32


AIL_digital_configuration

The function AIL_digital_configuration returns information about the specified digital driver.

void AIL_digital_configuration(
  HDIGDRIVER dig,
  S32 *rate,
  S32 *format,
  char *desc
);

In Parameters

dig
indicates the driver to inspect.

Out Parameters

rate
is a pointer to an integer that will receive the current output rate.
format
is a pointer to an integer that will receive one of the MILES_DIGITAL_FORMAT constants.
desc
is a pointer to a string buffer that will receive a description of the current sound driver. This buffer must be at least 128 characters in length.

Discussion

You can pass in NULL for any of the parameters that you're not interested in.

Under Win32 and Win64, the *desc string will also tell you if MSS is using DirectSound or the waveOut multimedia extensions (MME). It will also tell you if you are running in emulated DirectSound mode by prepending the description with the string"Emulated".

Group: Digital Audio Services
Related Basic Types: HDIGDRIVER, MILES_DIGITAL_FORMAT, S32, char, void


AIL_get_DirectSound_info

The function AIL_get_DirectSound_info returns the pointers to the DirectSound object currently being used by MSS.

void AIL_get_DirectSound_info(
  HSAMPLE S,
  LPDIRECTSOUND *lplpDS,
  LPDIRECTSOUNDBUFFER *lplpDSB
);

In Parameters

S
indicates the sample that you want to use.

Out Parameters

lplpDS
is a pointer to a LPDIRECTSOUND variable that will receive MSS's DirectSound object pointer.
lplpDSB
is a pointer to a LPDIRECTSOUNDBUFFER variable that will receive this sample's DirectSoundBuffer object pointer.

Discussion

This function is Windows only.

To get the pointer to the DirectSoundBuffer object, you must call AIL_start_sample at least once before calling this function (a DirectSoundBuffer object isn't assigned until you play the sample).

If MSS isn't currently using DirectSound, then this function will simply return.

You can pass NULL for any of the parameters that you aren't interested in.

Group: Digital Audio Services
Related Functions: AIL_open_digital_driver, AIL_start_sample
Related Basic Types: HSAMPLE, LPDIRECTSOUND, LPDIRECTSOUNDBUFFER, void


AIL_install_DIG_INI

The function AIL_install_DIG_INI installs and initializes the currently selected MSS .DIG driver file under DOS.

S32 AIL_install_DIG_INI(
  HDIGDRIVER *dig
);

Out Parameters

dig
points to an application variable of type HDIGDRIVER. If successful, AIL_install_DIG_INI will validate the application's HDIGDRIVER variable for use in subsequent function calls involving the driver. Otherwise, if an error occurs, *dig's value will be undefined.

Returns

Returns one of the MILES_INSTALL_STATUS constants.

Discussion

For compatibility with other Miles platforms, you should use the AIL_open_digital_driver function instead of this DOS-only function.

The SETSOUND Audio Configuration Utility program is provided as an extensible, device-independent installation and configuration program for MSS drivers. SETSOUND presents a list of all MSS drivers in the current working directory to the end user, allowing any desired driver to be selected and configured for use with an MSS application. The MSS example programs use AIL_install_MDI_INI and AIL_install_DIG_INI to load and initialize XMIDI and digital audio drivers in a single step, eliminating the need to specify driver names on the DOS command line and ensuring compatibility with all end-user I/O configurations.

RAD Game Tools strongly recommends use of the SETSOUND utility to create DIG.INI and MDI.INI files describing the user's driver choices and configurations. MSS applications may then use the AIL_install_DIG_INI and AIL_install_MDI_INI functions instead of calling AIL_install_DIG_driver_file or AIL_install_MDI_driver_file directly. This function calls AIL_read_INI to load the current DIG.INI file, and passes the parameters from the DIG.INI file to AIL_install_DIG_driver_file. Refer to the descriptions of these functions for a detailed summary of AIL_install_DIG_INI 's operation.

A return value of AIL_NO_INI_FILE generally arises from failure to run SETSOUND prior to launching the application. It does not indicate failure to detect sound hardware or problems related to driver initialization. These conditions are indicated by a return value of AIL_INIT_FAILURE.

You can use the AIL_set_redist_directory function to specify an alternate path to load the .DIG driver from (if the load fails from the current directory).

Group: Digital Audio Services
Related Sections: SETSOUND - MSS Sound Configuration Utility
Related Functions: AIL_close_digital_driver, AIL_install_DIG_INI, AIL_install_DIG_driver_file, AIL_install_MDI_INI, AIL_install_MDI_driver_file, AIL_open_digital_driver, AIL_read_INI, AIL_set_redist_directory
Related Basic Types: HDIGDRIVER, MILES_INSTALL_STATUS, S32


MILES_INSTALL_STATUS

The basic type MILES_INSTALL_STATUS specifies possible results from loading a DOS driver.

Fundamental Values

Value | Description
AIL_INIT_SUCCESS | specifies that the driver was successfully loaded and initialized. (Debugger value: 0).
AIL_NO_INI_FILE | specifies that no DIG.INI file was present. (Debugger value: 1).
AIL_INIT_FAILURE | specifies that a valid DIG.INI file was present but the specified driver could not be successfully loaded or initialized. (Debugger value: 2).

Group: Digital Audio Services
Related Functions: AIL_install_DIG_INI, AIL_install_MDI_INI


AIL_install_DIG_driver_file

The function AIL_install_DIG_driver_file installs and initializes an MSS-compatible .DIG driver file under DOS.

HDIGDRIVER AIL_install_DIG_driver_file(
  char const * filename,
  IO_PARMS * const *IO
);

In Parameters

filename
specifies the filename, including path, of the driver to install.
IO
specifies a particular I/O configuration to use when initializing the driver. If *IO is NULL or if the device cannot be detected using the specified parameters, the function will attempt to auto-detect the supported device using DOS environment strings or other driver-specific techniques.

Returns

A pointer to a dynamically allocated structure of type DIG_DRIVER, which may be passed by the application to subsequent function calls involving the driver; or NULL if an error occurs.

Discussion

For compatibility with other Miles platforms, you should use the AIL_open_digital_driver function instead of this DOS-only function.

Do not embed the .DIG files in any type of proprietary library file. You can leave them on your CD-ROM, if you use the AIL_set_redist_directory function to specify their location.

RAD Game Tools strongly recommends use of the SETSOUND utility to create .INI files describing the user's driver choices and configurations. MSS applications may then use the AIL_install_DIG_INI and AIL_install_MDI_INI functions instead of calling AIL_install_DIG_driver_file or AIL_install_MDI_driver_file directly.

You can use the AIL_set_redist_directory function to specify an alternate path to load the .MDI driver from (if the load fails from the current directory).

This function must not be invoked from an interrupt-based callback function.

Group: Digital Audio Services
Related Functions: AIL_close_digital_driver, AIL_get_IO_environment, AIL_install_DIG_INI, AIL_install_DIG_driver_file, AIL_install_DIG_driver_image, AIL_install_MDI_INI, AIL_install_MDI_driver_file, AIL_open_digital_driver, AIL_set_redist_directory
Related Basic Types: HDIGDRIVER, MILES_PREFERENCES, char const *
Related Structures: IO_PARMS


IO_PARMS

The structure IO_PARMS indicates specific hardware settings to use when installing a digital driver

struct IO_PARMS
{
  S16 IO;
  S16 IRQ;
  S16 DMA_8_bit;
  S16 DMA_16_bit;
  S32 IO_reserved[4];
};

In Members

IO
specifies the I/O address to use.
IRQ
specifies the IRQ to use.
DMA_8_bit
specifies the 8-bit DMA channel.
DMA_16_bit
specifies the 16-bit DMA channel.
IO_reserved[4]
reserved for MSS use.

Group: Digital Audio Services
Related Sections: DDK Function: 304H Verify Device I/O Parameters
Related Functions: AIL_get_IO_environment, AIL_install_DIG_driver_file
Related Basic Types: MILES_PREFERENCES, S16, S32
Related Structures: VDI_HDR


Creative EAX 2, 3, and 4 Providers

Discussion

Miles has extensive built-in support for EAX 2, 3, and 4. EAX is basically a set of environmental reverbation algorithms (and a few other DSP effects in EAX 4) that are performed in hardware on Creative Labs sound cards.

EAX 2 is fairly widely supported, even on non-Creative hardware. Unfortunately, like all hardware based systems, the quality, functionality, and even the stability varies dramatically from sound card to sound card. Intel's EAX 2 support sounds very different from the Creative sound cards, for example. In fact, even Creative's own cards sound very different from each other - an Audigy 4 card sounds quite different than an SBLive or an Audigy 1 - even when using identical EAX 2 software settings.

Due to this variablity, most developers are now authoring solely for software based 3D and environmental reverb systems like those in Miles 7 (even non-Miles developers like id Software have moved this direction). The CPU impact of even the most sophisticated reverb and DSP filters is so small (usually less than 3% in Miles, for example) that being able to author the sound and reverb mix of a game knowing that it always sounds the same is just too big of a win.

That said, if you can guarantee the latest Creative card and sound drivers (say, if you are doing a bundle deal with them, or co-marketing), then EAX hardware does sound great when you take the time to author for it.

That's why most developers that do choose to support EAX usually only support the Creative cards (and even then, usually only the latest hardware). It's hard enough to write a custom sound path just for EAX - let alone multiple ones for the various other sound cards out there.

Each section in this chapter will describe the properties that we expose for each level of the EAX API. Note that EAX 2 is the only API that non-Creative cards currently emulate, if you are trying for widest compatibility.

Creative EAX 2, 3, and 4 Providers
Creative's EAX 2 Properties
Creative's EAX 3 Properties
Creative's EAX 4 Properties
EAX_SAMPLE_SLOT_VOLUME | used to control the sound levels for a slot that the sample should play to
EAX_SAMPLE_SLOT_VOLUMES | used to control the sound levels for each the two possible slots that the sample can play into
EAX_REVERB | used to control the environmental reverb filter in the EAX 4 3D provider
EAX_AUTOGAIN | used to control the automatic gain control filter in the EAX 4 3D provider
EAX_AUTOWAH | used to control the autowah filter in the EAX 4 3D provider
EAX_CHORUS | used to control the chorus filter in the EAX 4 3D provider
EAX_DISTORTION | used to control the distortion filter in the EAX 4 3D provider
EAX_ECHO | used to control the echo filter in the EAX 4 3D provider
EAX_EQUALIZER | used to control the equalizer filter in the EAX 4 3D provider
EAX_FLANGER | used to control the flange filter in the EAX 4 3D provider
EAX_FSHIFTER | used to control the frequency shifter filter in the EAX 4 3D provider
EAX_VMORPHER | used to control the vocal morpher filter in the EAX 4 3D provider
EAX_PSHIFTER | used to control the pitch shifter filter in the EAX 4 3D provider
EAX_RMODULATOR | used to control the ring modulator filter in the EAX 4 3D provider


Creative's EAX 2 Properties

Discussion

The EAX 2 provider publishes many driver-level and sample-level properties that allow game developers to set interesting room styles. The EAX 2 provider also adds hardware support for occlusion and obstruction. Good use of room styles can add more to the "feel" of a game than the fanciest 3D spatialization.

When an HDIGDRIVER is opened with MSS_MC_EAX2 as the output channel specification, the following driver-level properties are accessible via AIL_output_filter_driver_property. Most applications should not control these properties directly; the standard digital audio API will provide plenty of control without sacrificing compatibility or causing internal state conflicts.

"Mute at maximum": this property controls whether sound is muted outside of the maximum distance (which is the default), or whether sound just stops falling off outside the maximum distance. As of this writing, the SBLive and Audigy drivers don't support mute at maximum.

"EAX environment selection" - this property allows you to set the reverb's room style. It should be set to one of the MILES_ROOM_TYPEconstants. You should generally use the AIL_set_room_type function instead of this property to set the room type for maximum compatibility.

"EAX effect volume": - this property controls the level at which the EAX reverb effect is applied to each voice. Its value ranges from 0.0 to 1.0. The maximum value of 1.0 turns overall reverb up to its highest possible level. Each time the value is halved, the reverb level is halved (decreased by 6 dB). Setting the effect volume to 0.0 turns off all reverb completely. This property accepts a 32-bit float (F32).

"EAX decay time": this property controls the decay time for the EAX reverb effect as it is applied to each voice, ranging from 0.1 to 20.0 seconds. This parameter determines the time in seconds required for the reverb effect to diminish by 60 dB. This property accepts a 32-bit float (F32).

"EAX damping": this property controls the damping factor (effect of frequency on decay time) for the EAX reverb effect as it is applied to each voice, ranging from 0.0 to 2.0. A value of 1.0 is treated as neutral, with the decay time equal for high, low, and mid-range frequencies. As the damping value increases above 1.0, the decay time of the high-frequency components of the sound increases relative to that of the mid-range and low-frequency components. This property accepts a 32-bit float (F32).

"EAX2 environment size": the Environment Size property sets the apparent size of the surrounding "room." The value of Environment Size can be considered a characteristic dimension of the room expressed in meters. Scaling Environment Size is equivalent to scaling all dimensions of the room by the same factor. This property accepts a 32-bit float (F32) from 1.0 to 100.0 linear meters.

"EAX2 environment diffusion": the Environment Diffusion property controls the echo density in the reverberation decay. It's set by default to 1.0, which provides the highest density. Reducing diffusion gives the reverberation a more "grainy" character that is especially noticeable with percussive sound sources. If you set a diffusion value of 0.0, the later reverberation sounds like a succession of distinct echoes. This property accepts a 32-bit float (F32) from 0.0 to 1.0 as a linear multiplier value.

"EAX2 room": the Room property is the master volume control for the reflected sound (both early reflections and reverberation) that EAX adds to all sound sources. It sets the maximum amount of reflections and reverberation added to the sound mix in the primary buffer (the listener). The value of the Room property ranges from 0 dB (the maximum amount) to -100 dB (no reflected sound at all). This property accepts a 32-bit integer (S32) from -10000.0 to 0.0 in hundredth of a dB.

"EAX2 room HF": the Room HF property further tweaks reflected sound by attenuating it at high frequencies. It controls a low-pass filter that applies globally to the reflected sound of all sound sources. The value of the Room HF property ranges from 0 dB (no filter) to -100 dB (virtually no reflected sound). This property accepts a 32-bit integer (S32) from -10000.0 to 0.0 in hundredth of a dB.

"EAX2 decay HF Ratio": the Decay HF Ratio property sets the spectral quality of the Decay Time parameter. It is the ratio of high-frequency decay time relative to the time set by Decay Time. The Decay HF Ratio value 1.0 is neutral: the decay time is equal for all frequencies. As Decay HF Ratio increases above 1.0, the high-frequency decay time increases so it's longer than the decay time at low frequencies. You hear a more brilliant reverberation with a longer decay at high frequencies. As the Decay HF Ratio value decreases below 1.0, the high-frequency decay time decreases so it's shorter than the decay time of the low frequencies. You hear a more natural reverberation. This property accepts a 32-bit float (F32) from 0.1 to 20.0 as a linear multiplier value.

"EAX2 reflections": the Reflections property controls the overall amount of initial reflections relative to the Room property. (The Room property sets the overall amount of reflected sound: both initial reflections and later reverberation.) The value of Reflections ranges from a maximum of 10 dB to a minimum of -100 dB (no initial reflections at all), and is corrected by the value of the Room property. The Reflections property does not affect the subsequent reverberation decay. This property accepts a 32-bit integer (S32) from -10000.0 to 1000.0 in hundredth of a dB.

"EAX2 reflections delay": the Reflections Delay property is the amount of delay between the arrival time of the direct path from the source to the first reflection from the source. It ranges from 0 to 300 milliseconds. You can reduce or increase Reflections Delay to simulate closer or more distant reflective surfaces-and therefore control the perceived size of the room. This property accepts a 32-bit float (F32) from 0.0 to 0.3 in seconds.

"EAX2 reverb": the Reverb property controls the overall amount of later reverberation relative to the Room property. (The Room property sets the overall amount of both initial reflections and later reverberation.) The value of Reverb ranges from a maximum of 20 dB to a minimum of -100 dB (no late reverberation at all). This property accepts a 32-bit integer (S32) from -10000.0 to 2000.0 in hundredth of a dB.

"EAX2 reverb delay": the Reverb Delay property defines the begin time of the late reverberation relative to the time of the initial reflection (the first of the early reflections). It ranges from 0 to 100 milliseconds. Reducing or increasing Reverb Delay is useful for simulating a smaller or larger room. This property accepts a 32-bit float (F32) from 0.0 to 0.1 in seconds.

"EAX2 room rolloff": the Room Rolloff property is one of two methods available in EAX to attenuate the reflected sound (containing both reflections and reverberation) according to source-listener distance. It's defined the same way as DirectSound's Rolloff Factor, but operates on reflected sound instead of direct-path sound. Setting the Room Rolloff Factor value to 1.0 specifies that the reflected sound will decay by 6 dB every time the distance doubles. Any value other than 1.0 is equivalent to a scaling factor applied to the quantity specified by ((Source listener distance) -(Minimum Distance)). Minimum distance is a DirectSound sound-source parameter that specifies the inner border for distance rolloff effects: if the source comes closer to the listener than the minimum distance, the direct-path sound isn't increased as the source comes closer to the listener, and neither is the reflected sound. This property accepts a 32-bit float (F32) from 0.1 to 10.0 as a linear multiplier value.

"EAX2 air absorption": the Air Absorption HF property controls the distance-dependent attenuation at high frequencies caused by the propagation medium. It applies to both the direct path and reflected sound. You can use Air Absorption HF to simulate sound transmission through foggy air, dry air, smoky atmosphere, and so on. The default value is -0.05 dB per meter, which roughly corresponds to typical condition of atmospheric humidity, temperature, and so on. Lowering the value simulates a more absorbent medium (more humidity in the air, for example); raising the value simulates a less absorbent medium (dry desert air, for example). This property accepts a 32-bit float (F32) from -100.0 to 0.0 as hundredths of a dB per meter.

"EAX2 flags": the Flags property uses its six low-order bits to set six listener-property flags. Five of these flags, the "scale flags," set the control that listener property environment Size has over five lower-level listener properties. The sixth flag prevents excessive decay times at high frequencies. See the EAX 2 documentation for more information on this property.

The following EAX 2 sample-level properties may be accessed by calling AIL_sample_stage_property with the SP_OUTPUT stage identifier:

"EAX2 sample direct": the Direct property is a low-level property that applies a relative correction to this sound source's direct-path intensity. (Direct-path intensity is the level of the sound source after attenuation for distance, orientation, and so on.) The Direct property allows you to apply a manual correction in addition to the effect of the DirectSound parameters distance, rolloff factor, orientation, and cone angles and to the effect of other EAX sound-source properties described in this section. The default value of 0 adds no correction to direct-path sound. This property accepts a 32-bit integer (S32) from -10000.0 to 1000.0 in hundredth of a dB.

"EAX2 sample direct HF": the Direct HF property is a related low-level property that applies a relative correction to the high-frequency component of the sound source's direct-path intensity. It has the same relationship to the high-frequency direct-path components of other DirectSound and EAX properties that the Direct property has to the full-frequency direct-path intensity. This property accepts a 32-bit integer (S32) from -10000.0 to 0.0 in hundredth of a dB.

"EAX2 sample room": the Room property is a low-level sound-source property that's defined the same way as the listener (global) Room property: it is the volume control for reflected sound (early reflections and reverberation). In this case, however, Room applies only to this sound source, and therefore affects only the reflected sound added to this source. It is an additive property; its setting is added to the total reflected sound value for this source that is specified by all other EAX listener and source properties. This property accepts a 32-bit integer (S32) from -10000.0 to 1000.0 in hundredth of a dB.

"EAX2 sample room HF": the Room HF property is a low-level sound-source property that is defined the same way as the listener Room HF property, but in this case is applied only to this sound source. It controls a low-pass filter that applies to the reflected sound added to this source. The value of Room HF ranges from 0 dB (no filter) to -100 dB (virtually no reflected sound). This is an additive property; its setting is added to the listener Room HF property and the other sound-source properties to determine how filtered the reflected sound for this source. This property accepts a 32-bit integer (S32) from -10000.0 to 0.0 in hundredth of a dB.

"EAX2 sample obstruction": the Obstruction property specifies the amount of obstruction muffling to apply to a sound source's direct-path sound. Obstruction occurs when an object lies between a sound source and a listener who occupy the same room. You should generally use the AIL_set_sample_obstruction function instead of this property to set the obstruction for compatibility with other 3D providers. The direct path from source to listener is muffled by the obstruction, but the reflected sound from the source remains unchanged. This property accepts a 32-bit integer (S32) from -10000.0 to 0.0 in hundredth of a dB.

"EAX2 sample obstruction LF ratio": the Obstruction LF Ratio property affects the spectral quality of obstruction set by the Obstruction property: it specifies the obstruction attenuation at low frequencies relative to the attenuation at high frequencies. The minimum value of 0.0 (the default value) specifies no attenuation at low frequencies; the maximum value of 1.0 specifies the same low-frequency attenuation as high-frequency attenuation. Note that adjusting Obstruction LF Ratio alone has no effect if Obstruction is set to 0. This property accepts a 32-bit float (F32) from 0.0 to 1.0 as a linear multiplier value.

"EAX2 sample occlusion": the Occlusion property specifies the amount of occlusion muffling to apply to a sound source's direct sound and to its reflected sound. Occlusion occurs when the listener is in one room or environment, the sound source is in another room or environment, and the listener hears the sound through a separating wall or through an opened or closed door or window. You should generally use the AIL_set_sample_occlusion function instead of this property to set the occlusion for compatibility with other 3D providers. Both the direct sound and the reflected sound from the sound source are muffled by the occlusion. This property accepts a 32-bit integer (S32) from -10000.0 to 0.0 in hundredth of a dB.

"EAX2 sample occlusion LF ratio": the Occlusion LF Ratio property affects the spectral quality of occlusion set by the Occlusion property: it specifies the occlusion attenuation at low frequencies relative to the attenuation at high frequencies. The minimum value of 0.0 specifies no attenuation at low frequencies; the maximum value of 1.0 specifies the same low-frequency attenuation as high-frequency attenuation. The default setting of 0.25 specifies that low frequencies are attenuated much less than high frequencies. Note that adjusting Occlusion LF Ratio alone has no effect if Occlusion is set to 0. This property accepts a 32-bit float (F32) from 0.0 to 1.0 as a linear multiplier value.

"EAX2 sample occlusion room ratio": the Occlusion Room Ratio property specifies the additional amount of occlusion attenuation to be applied to reflected sound (early reflections and reverberation). The minimum value of 0.0 specifies no additional reflected sound occlusion attenuation-that is, that direct-path and reflected sound attenuation occurs equally in the amount set by the Occlusion property. The maximum value of 10.0 specifies that the reflected sound is equal to 10 times the setting of Occlusion. This property accepts a 32-bit float (F32) from 0.0 to 10.0 as a linear multiplier value.

"EAX2 sample room rolloff": the Room Rolloff Factor property is a low-level sound-source property that is defined the same way as the listener (global) Room Rolloff property: it is one of two methods available in EAX to attenuate the reflected sound (early reflections and reverberation) according to source-listener distance. In this case, however, Room Rolloff applies only to this sound source, and therefore affects only the reflected sound generated by this source. Room Rolloff is an additive property; its setting is added to the listener Room Rolloff setting to get the final room rolloff multiplier value for that source. This property accepts a 32-bit float (F32) from 0.0 to 10.0 as a linear multiplier value.

"EAX2 sample air absorption": the Air Absorption Factor property is a multiplier value for the air absorption value set by the listener property Air Absorption HF. The resultant air absorption value applies only to this sound source. This property accepts a 32-bit float (F32) from 0.0 to 10.0 as a linear multiplier value.

"EAX2 sample outside volume HF": the Outside Volume HF property enhances the directivity effect provided by DirectSound 3D for individual sound sources. A directive sound source points in a specified direction. The source sounds at full volume when the listener is directly in front of the source; it's attenuated as the listener circles away from the front, with the maximum attenuation obtained in the back.

"EAX2 sample flags": the Flags property uses its three low-order bits to set three sound-source-property flags. These flags determine whether or not you want the EAX engine to automatically adjust the intensity and tonal color of the reflected sound or the tonal color of the direct-path sound for a source according to the setting of DirectSound's position and directivity parameters. See the EAX 2 documentation for more details on this property.

These EAX 2 property descriptions are taken almost verbatim from the EAX 2 documentation - see the EAX 2 docs for more information.

Be sure to review the How do I use multi-channel sound output in Miles? FAQ in conjunction with the material above.

Group: Creative EAX 2, 3, and 4 Providers
Related Functions: AIL_output_filter_driver_property, AIL_sample_stage_property, AIL_set_room_type, AIL_set_sample_obstruction, AIL_set_sample_occlusion
Related Basic Types: MILES_ROOM_TYPE
Related FAQs: How do I use multi-channel sound output in Miles?


Creative's EAX 3 Properties

Discussion

The EAX 3 provider publishes many driver-level and sample-level properties that allow game developers to set interesting room styles. The EAX 3 provider also adds hardware support for exclusion which sound really nice on an Audigy card. Good use of room styles can add more to the "feel" of a game than the fanciest 3D spatialization.

When an HDIGDRIVER is opened with MSS_MC_EAX3 as the output channel specification, the following driver-level properties are accessible via AIL_output_filter_driver_property. Most applications should not control these properties directly; the standard digital audio API will provide plenty of control without sacrificing compatibility or causing internal state conflicts.

"Mute at maximum": this property controls whether sound is muted outside of the maximum distance (which is the default), or whether sound just stops falling off outside the maximum distance. As of this writing, the SBLive and Audigy drivers don't support mute at maximum.

All of the EAX driver-level properties.

All of the EAX 2 driver-level properties.

"EAX3 room LF": the Room LF property further tweaks reflected sound by attenuating it at low frequencies. It controls a high-pass filter that applies globally to the reflected sound of all sound sources. The value of the Room LF property ranges from 0 dB (no filter) to -100 dB (virtually no reflected sound). This property accepts a 32-bit integer (S32) from -10000.0 to 0.0 in hundredth of a dB.

"EAX3 decay LF ratio": the Decay LF Ratio property sets the spectral quality of the Decay Time parameter. It is the ratio of low-frequency decay time relative to the time set by Decay Time. The Decay LF Ratio value 1.0 is neutral: the decay time is equal for all frequencies. As Decay LF Ratio increases above 1.0, the low-frequency decay time increases so it's longer than the decay time at high frequencies. You hear a more brilliant reverberation with a longer decay at low frequencies. As the Decay LF Ratio value decreases below 1.0, the low-frequency decay time decreases so it's shorter than the decay time of the high frequencies. You hear a more less natural reverberation. This property accepts a 32-bit float (F32) from 0.1 to 20.0 as a linear multiplier value.

"EAX3 reflections pan": the Reflections Pan property is a 3D vector that controls the spatial distribution of the cluster of early reflections. The direction of this vector controls the global direction of the reflections, while its magnitude controls how focused the reflections are towards this direction. The direction of the vector is interpreted in the coordinate system of the user, without taking into account the orientation of the virtual listener. For instance, assuming a fourpoint loudspeaker playback system, setting Reflections Pan to (0.0, 0.0, 0.7) means that the reflections are panned to the front speaker pair, whereas as setting of (0.0, 0.0, -0.7) pans the reflections towards the rear speakers. If the magnitude of Reflections Pan is zero (the default setting), the early reflections come evenly from all directions. As the magnitude increases, the reflections become more focused in the direction pointed to by the vector. A magnitude of 1.0 represents the extreme case where all reflections come from a single direction, and is therefore unusual. The EAX 3.0 reverberation engine does not support magnitudes larger than 0.7. Although larger magnitudes are allowed (up to 1.0), it is safer for the application to limit the magnitude to 0.7, because this limitation of the EAX reverberation engine may be removed in future versions of EAX. This property accepts a 32-bit float (F32).

"EAX3 reverb pan": this Reverb Pan property works exactly like the Reflections pan property, but applies to the late reverberation. This property accepts a 32-bit float (F32).

"EAX3 echo time" and "EAX3 echo depth": the Echo Time property determines the time lag of an echo in the reverberation decay. The strength of this effect is controlled by the settings of the Echo Depth and Environment Diffusion properties. For the maximum value of Diffusion, 1.0, the echo is restricted to the onset of the reverberation and perceptible mainly with percussive sounds. For lower values of Diffusion, the echo repeats cyclically along the reverberation decay, with a period equal to Echo Time. This creates an amplitude modulation in the decay, which washes off towards the end of the decay for intermediate settings of Diffusion. If Diffusion is minimal, the echo persists during the whole decay. The default value of Echo Time is 250 ms, which specifies a rate of 4 echoes per second. These properties accepts a 32-bit float (F32).

"EAX3 modulation time" and "EAX3 modulation depth": the Modulation properties are similar to the Echo properties. However, instead of an echo (or amplitude modulation), they control a pitch modulation in the reverberation decay. The property Modulation Depth controls the pitch range of this modulation, while Modulation Time controls the rate of the modulation. The default modulation time is 250 ms, which specifies a rate of 4 cycles per second. Unlike the Echo properties, the Modulation properties create a modulation that persists during the whole reverberation decay (irrespective of the setting of the Environment diffusion property). These properties accepts a 32-bit float (F32).

"EAX3 HF reference" and "EAX3 LF reference": the HF Reference and LF Reference properties determine respectively the frequencies at which the high-frequency effect and the low-frequency effects created by EAX properties are measured. Note that, for listener properties, it is necessary to maintain a factor of at least 10 between these two reference frequencies so that low-frequency and high-frequency properties can be accurately controlled and can produce independent effects. In other words, the LF Reference value should be less than 1/10 of the HF Reference value. The HF Reference value also applies to the source properties for all sources. As a result, it is safe to adopt the same setting of HF Reference for all the environment presets used in a given application. Otherwise, changing the Environment preset while the application is running will affect certain properties that should remain characteristics of the sources (such as their directivity at high frequencies, specified by the source property Outside Volume HF). These property accepts a 32-bit float (F32) from 20 to 20000.0 as sound frequencies.

The following EAX 3 sample-level properties may be accessed by calling AIL_sample_stage_property with the SP_OUTPUT stage identifier:

All of the EAX 2 sample-level properties.

"EAX3 sample occlusion direct ratio": the Occlusion Direct Ratio property controls the amount of attenuation and filtering applied to the direct path for a given setting of the Occlusion property. The attenuation obtained at the reference high frequency is determined by multiplying the Occlusion property value by the Occlusion Room Ratio or the Occlusion Direct Ratio. When the Ratio value is set between 0.0 and 1.0, the effect is equivalent, for low and high frequencies, to scaling the setting of the Occlusion property by that value. If the value is larger than 1.0, that is only true at high frequencies; at low frequencies, the attenuation is such that the filter slope (difference between low frequencies and high frequencies) remains the same as for a setting of 1.0.

"EAX3 sample exclusion": the Exclusion property specifies the amount of exclusion muffling to apply to a sound source's reflected sound. You should generally use the AIL_set_sample_exclusion function instead of this property to set the occlusion for compatibility with other 3D providers. Only the reflected sound from the sound source are muffled by the exclusion. This property accepts a 32-bit integer (S32) from -10000.0 to 0.0 in hundredth of a dB.

"EAX3 sample exclusion LF ratio": the Exclusion LF Ratio property affects the spectral quality of exclusion set by the Exclusion property: it specifies the exclusion attenuation at low frequencies relative to the attenuation at high frequencies. The minimum value of 0.0 specifies no attenuation at low frequencies; the maximum value of 1.0 specifies the same low-frequency attenuation as high-frequency attenuation. The default setting of 0.25 specifies that low frequencies are attenuated much less than high frequencies. Note that adjusting Exclusion LF Ratio alone has no effect if Exclusion is set to 0. This property accepts a 32-bit float (F32) from 0.0 to 1.0 as a linear multiplier value.

"EAX3 sample doppler factor": the Doppler Factor property is a low-level sound-source property that is defined the same way as the global Doppler Factor property provided in DirectSound only for reflected sound. A value of 1.0 provides natural Doppler effects according to the movement of the source relative to the listener. A value larger than 1.0 will exaggerate these effects. A value of 0.0 will eliminate Doppler effects.

These EAX 3 property descriptions are taken almost verbatim from the EAX 3 documentation - see the EAX 3 docs for more information.

Be sure to review the How do I use multi-channel sound output in Miles? FAQ in conjunction with the material above.

Group: Creative EAX 2, 3, and 4 Providers
Related Functions: AIL_output_filter_driver_property, AIL_sample_stage_property, AIL_set_sample_exclusion
Related FAQs: How do I use multi-channel sound output in Miles?


Creative's EAX 4 Properties

Discussion

The EAX 4 provider publishes many driver-level and sample-level properties that allow game developers to set interesting room styles. These properties include all of the EAX 3 properties too.

But more interesting are the new EAX 4 features, which provide hardware support for many common DSP filters. EAX does this by providing multiple "slots" that you can load a DSP filter into. You then direct your sound effects into one of these slots to hear the filtered sound.

There are currently four of these slots, but the first two are fixed-function: slot 0 is environmental reverb, and slot 1 is a chorus filter. You can load other filters into slots 2 and 3. You can even have multiple environmental reverbs, one in slot 0, one is slot 2 or 3, for example.

Each 3D sound can only be routed to either no slots, one slot, or two slots at a time. That means you can have a single sound being flanged and ring modulated at once, for example.

Miles massively refactors the EAX 4 API (which is otherwise quite complicated). To load a filter, you simply set the parameters for that filter - this will first load the filter, and then set the parameters. To activate a filter, you simply set the volume - this will send the sound to the filter and then set the volume level.

All of the filters are loaded by passing a particular structure to the AIL_output_filter_driver_property function. Each structure is specific to the filter that you are trying to load. We don't change these structures at all from the EAX versions, so you can also read the EAX docs for more info on each filter.

The best way to learn how to use the EAX 4 features is to check out the EAX4EXAM.CPP demo program - it is an extremely simple and clear example that shows how to use each of the EAX 4 filters. Also, be sure to review the How do I use multi-channel sound output in Miles? FAQ in conjunction with the material below.

When an HDIGDRIVER is opened with MSS_MC_EAX4 as the output channel specification, the following driver-level properties are accessible via AIL_output_filter_driver_property:

All of the EAX driver-level properties.

All of the EAX 2 driver-level properties.

All of the EAX 3 driver-level properties.

"EAX4 Reverb parameters": this preference takes a pointer to a EAX_REVERB structure. When you set this preference, it first loads the Reverb filter (if it hasn't already been loaded), and then it updates each of your settings. The Reverb filter can be loaded into slots 0, 2 and/or 3 - it is the basic EAX environmental reverb filter. See the EAX 4 documentation for more details on this complicated filter.

"EAX4 Auto Gain parameters": this preference takes a pointer to a EAX_AUTOGAIN structure. When you set this preference, it first loads the Auto Gain filter (if it hasn't already been loaded), and then it updates each of your settings. The Auto Gain filter can be loaded into slots 2 and/or 3. See the EAX 4 documentation for more details on this simple filter.

"EAX4 Autowah parameters": this preference takes a pointer to a EAX_AUTOWAH structure. When you set this preference, it first loads the Autowah filter (if it hasn't already been loaded), and then it updates each of your settings. The Autowah filter can be loaded into slots 2 and/or 3. See the EAX 4 documentation for more details on this basic filter.

"EAX4 Chorus parameters": this preference takes a pointer to a EAX_CHORUS structure. When you set this preference, it first loads the Chorus filter (if it hasn't already been loaded), and then it updates each of your settings. The Chorus filter can be loaded into slots 1, 2 and/or 3. See the EAX 4 documentation for more details on this common filter.

"EAX4 Distortion parameters": this preference takes a pointer to a EAX_DISTORTION structure. When you set this preference, it first loads the Distortion filter (if it hasn't already been loaded), and then it updates each of your settings. The Distortion filter can be loaded into slots 2 and/or 3. See the EAX 4 documentation for more details on this filter.

"EAX4 Echo parameters": this preference takes a pointer to a EAX_ECHO structure. When you set this preference, it first loads the Echo filter (if it hasn't already been loaded), and then it updates each of your settings. The Echo filter can be loaded into slots 2 and/or 3. See the EAX 4 documentation for more details on this filter.

"EAX4 Equalizer parameters": this preference takes a pointer to a EAX_EQUALIZER structure. When you set this preference, it first loads the Equalizer filter (if it hasn't already been loaded), and then it updates each of your settings. The Equalizer filter can be loaded into slots 2 and/or 3. See the EAX 4 documentation for more details on this filter.

"EAX4 Flanger parameters": this preference takes a pointer to a EAX_FLANGER structure. When you set this preference, it first loads the Flanger filter (if it hasn't already been loaded), and then it updates each of your settings. The Flanger filter can be loaded into slots 2 and/or 3. See the EAX 4 documentation for more details on this filter.

"EAX4 FShifter parameters": this preference takes a pointer to a EAX_FSHIFTER structure. When you set this preference, it first loads the Frequency shifter filter (if it hasn't already been loaded), and then it updates each of your settings. The Frequency shifter filter can be loaded into slots 2 and/or 3. See the EAX 4 documentation for more details on this filter.

"EAX4 VMorpher parameters": this preference takes a pointer to a EAX_VMORPHER structure. When you set this preference, it first loads the Vocal Morpher filter (if it hasn't already been loaded), and then it updates each of your settings. The Vocal Morpher filter can be loaded into slots 2 and/or 3. See the EAX 4 documentation for more details on this filter.

"EAX4 PShifter parameters": this preference takes a pointer to a EAX_PSHIFTER structure. When you set this preference, it first loads the Pitch Shifter filter (if it hasn't already been loaded), and then it updates each of your settings. The Pitch Shifter filter can be loaded into slots 2 and/or 3. See the EAX 4 documentation for more details on this filter.

"EAX4 RModulator parameters": this preference takes a pointer to a EAX_RMODULATOR structure. When you set this preference, it first loads the Ring Modulator filter (if it hasn't already been loaded), and then it updates each of your settings. The Ring Modulator filter can be loaded into slots 2 and/or 3. See the EAX 4 documentation for more details on this filter.

The EAX 4 sample-level properties include:

All of the EAX 2 sample-level properties.

All of the EAX 3 sample-level properties.

"EAX4 slot volumes": this preference takes a pointer to a EAX_SAMPLE_SLOT_VOLUMES structure. It will both activate the filter for this sample and set your volume levels.

"Get EAX4 slot volumes": this preference takes a pointer to a EAX_SAMPLE_SLOT_VOLUMES structure and fills it with the current hardware settings.

Group: Creative EAX 2, 3, and 4 Providers
Related Functions: AIL_output_filter_driver_property
Related Structures: EAX_AUTOGAIN, EAX_AUTOWAH, EAX_CHORUS, EAX_DISTORTION, EAX_ECHO, EAX_EQUALIZER, EAX_FLANGER, EAX_FSHIFTER, EAX_PSHIFTER, EAX_REVERB, EAX_RMODULATOR, EAX_SAMPLE_SLOT_VOLUMES, EAX_VMORPHER
Related FAQs: How do I use multi-channel sound output in Miles?


EAX_SAMPLE_SLOT_VOLUME

The structure EAX_SAMPLE_SLOT_VOLUME used to control the sound levels for a slot that the sample should play to

struct EAX_SAMPLE_SLOT_VOLUME
{
  S32 Slot;
  S32 Send;
  S32 SendHF;
  S32 Occlusion;
  F32 OcclusionLFRatio;
  F32 OcclusionRoomRatio;
  F32 OcclusionDirectRatio;
};

In Members

Slot
specifies the slot for this volume control. EAX 4 currently supports 4 slots (so 0, 1, 2 or 3).
Send
specifies the volume of this sample for this slot in standard EAX attenuation units (-10000 to 0 fixed point millibels, default 0.0).
SendHF
specifies additional attenuation for this slot for high frequencies in standard EAX attenuation units (-10000 to 0 fixed point millibels, default 0.0).
Occlusion
specifies the occlusion level of this sample for this slot in standard EAX attenuation units (-10000 to 0 fixed point millibels, default 0.0).
OcclusionLFRatio
specifies the occlusion attenuation at low frequencies relative to high frequencies (0.0 to 1.0, default 0.25).
OcclusionRoomRatio
specifies the occlusion attenuation for the reflected (wet) sound path (0.0 to 10.0, default 1.5).
OcclusionDirectRatio
specifies the occlusion attenuation for the direct (dry) sound path (0.0 to 10.0, default 1.0).

Discussion

In EAX 4, you can only send a particular sound sample to two slots at once.

Group: Creative EAX 2, 3, and 4 Providers
Related Basic Types: F32, S32
Related Structures: EAX_SAMPLE_SLOT_VOLUMES


EAX_SAMPLE_SLOT_VOLUMES

The structure EAX_SAMPLE_SLOT_VOLUMES used to control the sound levels for each the two possible slots that the sample can play into

struct EAX_SAMPLE_SLOT_VOLUMES
{
  U32 NumVolumes;
  EAX_SAMPLE_SLOT_VOLUME volumes[2];
};

In Members

NumVolumes
specifies the number of slots that you want to send this sound to. This can be 0, 1 or 2 slots.
volumes
specifies settings for each of the slots that you want to point this sound into.

Discussion

In EAX 4, you can only send a particular sound sample to two slots at once.

Group: Creative EAX 2, 3, and 4 Providers
Related Sections: Creative's EAX 4 Properties
Related Basic Types: U32
Related Structures: EAX_SAMPLE_SLOT_VOLUME


EAX_REVERB

The structure EAX_REVERB used to control the environmental reverb filter in the EAX 4 3D provider

struct EAX_REVERB
{
  S32 Slot;
  S32 Volume;
  MILES_ROOM_TYPE Environment;
  F32 EnvironmentSize;
  F32 EnvironmentDiffusion;
  S32 Room;
  S32 RoomHF;
  S32 RoomLF;
  F32 DecayTime;
  F32 DecayHFRatio;
  F32 DecayLFRatio;
  S32 Reflections;
  F32 ReflectionsDelay;
  F32 ReflectionsPanX;
  F32 ReflectionsPanY;
  F32 ReflectionsPanZ;
  S32 Reverb;
  F32 ReverbDelay;
  F32 ReverbPanX;
  F32 ReverbPanY;
  F32 ReverbPanZ;
  F32 EchoTime;
  F32 EchoDepth;
  F32 ModulationTime;
  F32 ModulationDepth;
  F32 AirAbsorptionHF;
  F32 HFReference;
  F32 LFReference;
  F32 RoomRolloffFactor;
  U32 Flags;
};

In Members

Slot
specifies the slot to query or set. Reverb can use slot 0, 2 and/or 3.
Volume
specifies the volume of this slot in standard EAX attenuation units (-10000 to 0 fixed point millibels, default 0.0).
Environment
specifies one of the room type environment constants (default ENVIRONMENT_GENERIC).
EnvironmentSize
specifies environment size in meters (default 7.5).
EnvironmentDiffusion
controls the echo density in the reverberation decay (0.0 to 1.0, default 1.0).
Room
specifies the room effect level (at mid frequencies) in standard EAX attenuation units (-10000 to 0 fixed point millibels, default -1000).
RoomHF
specifies the relative room effect level at high frequencies in standard EAX attenuation units (-10,000 to 0 fixed point millibels, default -100).
RoomLF
specifies the relative room effect level at low frequencies in standard EAX attenuation units (-10,000 to 0 fixed point millibels, default 0).
DecayTime
specifies the reverberation decay time at mid frequencies in seconds (0.1 to 20.0, default 1.49).
DecayHFRatio
specifies the high-frequency to mid-frequency decay time ratio (0.1 to 2.0, default 0.83).
DecayLFRatio
specifies the low-frequency to mid-frequency decay time ratio (0.1 to 2.0, default 1.0).
Reflections
controls the early reflections level relative to room effect in standard EAX attenuation units (-10000 to 0 fixed point millibels, default -2602).
ReflectionsDelay
specifies the initial reflection delay time from direct path to first reflection in seconds (0.0 to 0.3, default 0.007).
ReflectionsPanX
specifies the normalized X coordinate of the early reflections panning vector (default 0.0).
ReflectionsPanY
specifies the normalized Y coordinate of the early reflections panning vector (default 0.0).
ReflectionsPanZ
specifies the normalized Z coordinate of the early reflections panning vector (default 0.0).
Reverb
specifies the late reverberation level relative to room effect in standard EAX attenuation units (-10000 to 2000 fixed point millibels, default 200).
ReverbDelay
specifies the late reverberation delay time relative to initial reflection in seconds (0.0 to 0.1, default 0.011).
ReverbPanX
specifies the normalized X coordinate of the late reverberation panning vector (default 0.0).
ReverbPanY
specifies the normalized Y coordinate of the late reverberation panning vector (default 0.0).
ReverbPanZ
specifies the normalized Z coordinate of the late reverberation panning vector (default 0.0).
EchoTime
specifies the time lag of an echo in the reverberation decay in seconds (0.075 to 0.25, default 0.25).
EchoDepth
specifies a factor controlling the strength of the echo effect (0.0 to 1.0, default: 0.0).
ModulationTime
specifies rate of modulation in seconds (0.04 to 4.0, default: 0.25).
ModulationDepth
specifies a factor controlling the pitch range of the modulation effect (0.0 to 1.0, default: 0.0).
AirAbsorptionHF
specifies the change in level per meter at high frequencies (-100.0 to 0.0, default -5.0).
HFReference
specifies the reference high frequency in hertz (1000.0 to 20000.0, default 5000.0).
LFReference
specifies the reference low frequency in hertz (20.0 to 1000.0, default 250.0).
RoomRolloffFactor
specifies the a DS3D-style rolloff factor but for room effects (0 to 10.0, default 0,0).
Flags
modifies the behavior of properties - you can use one or more of these values:
1 = delay time adjusted by environment size,
2 = reflection level adjusted by environment size,
4 = reflection delay time adjusted by environment size,
8 = reverb level adjusted by environment size,
16 = reverb delay time adjusted by environment size,
64 = echo time adjusted by environment size,
128 = modulation time adjusted by environment size,
32 = limit high-frequency decay time according to air absorption.
Default: 255.

Discussion

See the EAX 4 documentation for technical details on this filter.

Group: Creative EAX 2, 3, and 4 Providers
Related Sections: Creative's EAX 4 Properties
Related Basic Types: F32, MILES_ROOM_TYPE, S32, U32


EAX_AUTOGAIN

The structure EAX_AUTOGAIN used to control the automatic gain control filter in the EAX 4 3D provider

struct EAX_AUTOGAIN
{
  S32 Slot;
  S32 Volume;
  U32 OnOff;
};

In Members

Slot
specifies the slot to query or set. Autogain can use slot 2 and/or 3.
Volume
specifies the volume of this slot in standard EAX attenuation units (-10000 to 0 fixed point millibels, default 0.0).
OnOff
switches the compressor on or off (1 or 0).

Discussion

See the EAX 4 documentation for technical details on this filter.

Group: Creative EAX 2, 3, and 4 Providers
Related Sections: Creative's EAX 4 Properties
Related Basic Types: S32, U32


EAX_AUTOWAH

The structure EAX_AUTOWAH used to control the autowah filter in the EAX 4 3D provider

struct EAX_AUTOWAH
{
  S32 Slot;
  S32 Volume;
  F32 AttackTime;
  F32 ReleaseTime;
  S32 Resonance;
  S32 PeakLevel;
};

In Members

Slot
specifies the slot to query or set. Autowah can use slot 2 and/or 3.
Volume
specifies the volume of this slot in standard EAX attenuation units (-10000 to 0 fixed point millibels, default 0.0).
AttackTime
specifies attack time in seconds (0.0001 to 1.0, default 0.06).
ReleaseTime
specifies the release time in seconds (0.0001 to 1.0, default 0.06).
Resonance
specifies the resonance of the filter in standard EAX attenuation units (600 to 6000 fixed point millibels, default 6000).
PeakLevel
specifies the peak level of the filter in standard EAX attenuation units (-9,000 to 9000 fixed point millibels, default 2100).

Discussion

See the EAX 4 documentation for technical details on this filter.

Group: Creative EAX 2, 3, and 4 Providers
Related Sections: Creative's EAX 4 Properties
Related Basic Types: F32, S32


EAX_CHORUS

The structure EAX_CHORUS used to control the chorus filter in the EAX 4 3D provider

struct EAX_CHORUS
{
  S32 Slot;
  S32 Volume;
  U32 Waveform;
  S32 Phase;
  F32 Rate;
  F32 Depth;
  F32 Feedback;
  F32 Delay;
};

In Members

Slot
specifies the slot to query or set. Chorus can use slot 1, 2 and/or 3.
Volume
specifies the volume of this slot in standard EAX attenuation units (-10000 to 0 fixed point millibels, default 0.0).
Waveform
selects the waveform - 0 = sinusoid, 1 = triangle.
Phase
specifies the chorus phase in degrees (-180 to 180, default 90).
Rate
specifies the chorus rate in hertz (0.0 to 10.0, default 1.1).
Depth
specifies the chorus depth (0 to 1, default 0.1).
Feedback
specifies the chorus feedback (-1 to 1, default 0.25).
Delay
specifies the delay in seconds (0.0002 to 0.016, default 0.016).

Discussion

See the EAX 4 documentation for technical details on this filter.

Group: Creative EAX 2, 3, and 4 Providers
Related Sections: Creative's EAX 4 Properties
Related Basic Types: F32, S32, U32


EAX_DISTORTION

The structure EAX_DISTORTION used to control the distortion filter in the EAX 4 3D provider

struct EAX_DISTORTION
{
  S32 Slot;
  S32 Volume;
  F32 Edge;
  S32 Gain;
  F32 LowPassCutOff;
  F32 EQCenter;
  F32 EQBandwidth;
};

In Members

Slot
specifies the slot to query or set. Distortion can use slot 2 and/or 3.
Volume
specifies the volume of this slot in standard EAX attenuation units (-10000 to 0 fixed point millibels, default 0.0).
Edge
controls the shape of the distortion (0.0 to 1.0, default 0.2).
Gain
specifies the low gain of this slot in standard EAX attenuation units (-6000 to 0 fixed point millibels, default -2600).
LowPassCutOff
specifies the cutoff of the filter pre-distortion in hertz (80.0 to 24000.0, default 8000).
EQCenter
specifies the center frequency of the EQ post-distortion in hertz (80.0 to 24000.0, default 3600).
EQBandwidth
specifies the bandwidth of the EQ post-distortion in hertz (80.0 to 24000.0, default 3600).

Discussion

See the EAX 4 documentation for technical details on this filter.

Group: Creative EAX 2, 3, and 4 Providers
Related Sections: Creative's EAX 4 Properties
Related Basic Types: F32, S32


EAX_ECHO

The structure EAX_ECHO used to control the echo filter in the EAX 4 3D provider

struct EAX_ECHO
{
  S32 Slot;
  S32 Volume;
  F32 Delay;
  F32 LRDelay;
  F32 Damping;
  F32 Feedback;
  F32 Spread;
};

In Members

Slot
specifies the slot to query or set. Echo can use slot 2 and/or 3.
Volume
specifies the volume of this slot in standard EAX attenuation units (-10000 to 0 fixed point millibels, default 0.0).
Delay
specifies the initial delay time in seconds (0.002 to 0.207, default 0.1).
LRDelay
specifies the delay time between the first and second taps in seconds (0.002 to 0.404, default 0.1).
Damping
controls a low-pass filter that dampens the echoes (0.0 to 0.99, default 0.5).
Feedback
controls the duration of echo repetition (0.0 to 1.0, default 0.5).
Spread
controls the left-right spread of the echoes (-1.0 to 1.0, default -1.0).

Discussion

See the EAX 4 documentation for technical details on this filter.

Group: Creative EAX 2, 3, and 4 Providers
Related Sections: Creative's EAX 4 Properties
Related Basic Types: F32, S32


EAX_EQUALIZER

The structure EAX_EQUALIZER used to control the equalizer filter in the EAX 4 3D provider

struct EAX_EQUALIZER
{
  S32 Slot;
  S32 Volume;
  S32 LowGain;
  F32 LowCutOff;
  S32 Mid1Gain;
  F32 Mid1Center;
  F32 Mid1Width;
  F32 Mid2Gain;
  F32 Mid2Center;
  F32 Mid2Width;
  S32 HighGain;
  F32 HighCutOff;
};

In Members

Slot
specifies the slot to query or set. The equalizer can use slot 2 and/or 3.
Volume
specifies the volume of this slot in standard EAX attenuation units (-10000 to 0 fixed point millibels, default 0.0).
LowGain
specifies the low gain of this slot in standard EAX attenuation units (-1800 to 1800 fixed point millibels, default 0).
LowCutOff
specifies the low cut off in hertz (50.0 to 800.0, default 200.0).
Mid1Gain
specifies the first middle gain of this slot in standard EAX attenuation units (-1800 to 1800 fixed point millibels, default 0).
Mid1Center
specifies the first middle center in hertz (200.0 to 3000.0, default 500.0).
Mid1Width
specifies the first middle width in octaves (0.01 to 1.0, default 1.0).
Mid2Gain
specifies the gain middle gain of this slot in standard EAX attenuation units (-1800 to 1800 fixed point millibels, default 0).
Mid2Center
specifies the second middle center in hertz (1000.0 to 8000.0, default 3000.0).
Mid2Width
specifies the second middle width in octaves (0.01 to 1.0, default 1.0).
HighGain
specifies the high gain of this slot in standard EAX attenuation units (-1800 to 1800 fixed point millibels, default 0).
HighCutOff
specifies the high cut off in hertz (4000.0 to 16000.0, default 6000.0).

Discussion

See the EAX 4 documentation for technical details on this filter.

Group: Creative EAX 2, 3, and 4 Providers
Related Sections: Creative's EAX 4 Properties
Related Basic Types: F32, S32


EAX_FLANGER

The structure EAX_FLANGER used to control the flange filter in the EAX 4 3D provider

struct EAX_FLANGER
{
  S32 Slot;
  S32 Volume;
  U32 Waveform;
  S32 Phase;
  F32 Rate;
  F32 Depth;
  F32 Feedback;
  F32 Delay;
};

In Members

Slot
specifies the slot to query or set. The flanger can use slot 2 and/or 3.
Volume
specifies the volume of this slot in standard EAX attenuation units (-10000 to 0 fixed point millibels, default 0.0).
Waveform
selects the waveform - 0 = sinusoid, 1 = triangle.
Phase
specifies the flange phase in degrees (-180 to 180, default 0).
Rate
specifies the flange rate in hertz (0.0 to 10.0, default 0.27).
Depth
specifies the flange depth (0.0 to 1.0, default 1.0).
Feedback
specifies the flange feedback (-1.0 to 1.0, default -0.5).
Delay
specifies the delay time in seconds (0.0002 to 0.004, default 0.002).

Discussion

See the EAX 4 documentation for technical details on this filter.

Group: Creative EAX 2, 3, and 4 Providers
Related Sections: Creative's EAX 4 Properties
Related Basic Types: F32, S32, U32


EAX_FSHIFTER

The structure EAX_FSHIFTER used to control the frequency shifter filter in the EAX 4 3D provider

struct EAX_FSHIFTER
{
  S32 Slot;
  S32 Volume;
  F32 Frequency;
  U32 LeftDirection;
  U32 RightDirection;
};

In Members

Slot
specifies the slot to query or set. The frequency shifter can use slot 2 and/or 3.
Volume
specifies the volume of this slot in standard EAX attenuation units (-10000 to 0 fixed point millibels, default 0.0).
Frequency
specifies the frequency in hertz (0.0 to 24000.0, default 0.0).
LeftDirection
specifies the left speaker direction - 0 = down, 1 = up, 2 = off.
RightDirection
specifies the right speaker direction - 0 = down, 1 = up, 2 = off.

Discussion

See the EAX 4 documentation for technical details on this filter.

Group: Creative EAX 2, 3, and 4 Providers
Related Sections: Creative's EAX 4 Properties
Related Basic Types: F32, S32, U32


EAX_VMORPHER

The structure EAX_VMORPHER used to control the vocal morpher filter in the EAX 4 3D provider

struct EAX_VMORPHER
{
  S32 Slot;
  S32 Volume;
  U32 PhonemeA;
  S32 PhonemeACoarseTuning;
  U32 PhonemeB;
  S32 PhonemeBCoarseTuning;
  U32 Waveform;
  F32 Rate;
};

In Members

Slot
specifies the slot to query or set. The vocal morpher can use slot 2 and/or 3.
Volume
specifies the volume of this slot in standard EAX attenuation units (-10000 to 0 fixed point millibels, default 0.0).
PhonemeA
specifies the first phoneme from 0 to 29 - A E I O U AA AE AH AO EH ER IH IY UH UW B D G J K L M N P R S T V Z (default 0 - A).
PhonemeACoarseTuning
specifies the amount of morphing in semitones for the first phoneme (-24 to 24, default 0).
PhonemeB
specifies the second phoneme from 0 to 29 - A E I O U AA AE AH AO EH ER IH IY UH UW B D G J K L M N P R S T V Z (default 10 - ER).
PhonemeBCoarseTuning
specifies the amount of morphing in semitones for second phoneme (-24 to 24, default 0).
Waveform
selects the waveform - 0 = sinusoid, 1 = triangle, 2 = sawtooth.
Rate
specifies the morphing rate in hertz (0.0 to 10.0, default 1.41).

Discussion

See the EAX 4 documentation for technical details on this filter.

Group: Creative EAX 2, 3, and 4 Providers
Related Sections: Creative's EAX 4 Properties
Related Basic Types: F32, S32, U32


EAX_PSHIFTER

The structure EAX_PSHIFTER used to control the pitch shifter filter in the EAX 4 3D provider

struct EAX_PSHIFTER
{
  S32 Slot;
  S32 Volume;
  S32 CoarseTune;
  S32 FineTune;
};

In Members

Slot
specifies the slot to query or set. The pitch shifter can use slot 2 and/or 3.
Volume
specifies the volume of this slot in standard EAX attenuation units (-10000 to 0 fixed point millibels, default 0.0).
CoarseTune
specifies the amount of pitch shift in semitones (-12 to 12, default 12).
FineTune
specifies the amount of pitch shift in cents (-50 to 50, default 0).

Discussion

See the EAX 4 documentation for technical details on this filter.

Group: Creative EAX 2, 3, and 4 Providers
Related Sections: Creative's EAX 4 Properties
Related Basic Types: S32


EAX_RMODULATOR

The structure EAX_RMODULATOR used to control the ring modulator filter in the EAX 4 3D provider

struct EAX_RMODULATOR
{
  S32 Slot;
  S32 Volume;
  F32 Frequency;
  F32 HighPassCutOff;
  U32 Waveform;
};

In Members

Slot
specifies the slot to query or set. The Ring modulator can use slot 2 and/or 3.
Volume
specifies the volume of this slot in standard EAX attenuation units (-10000 to 0 fixed point millibels, default 0.0).
Frequency
specifies the frequency of the modulation in hertz (0.0 to 8000.0, default 440.0).
HighPassCutOff
specifies the cutoff frequency of high-pass filter in hertz (0.0 to 24000.0, default 800.0).
Waveform
selects the waveform - 0 = sinusoid, 1 = triangle, 2 = sawtooth.

Discussion

See the EAX 4 documentation for technical details on this filter.

Group: Creative EAX 2, 3, and 4 Providers
Related Sections: Creative's EAX 4 Properties
Related Basic Types: F32, S32, U32


Miles SRS Circle Surround Provider

Discussion

The SRS Circle Surround 6.1 Encoder for MILES Sound System ("SRS Miles Encoder") is a run-time surround sound encoder. Using home-theater and gaming surround sound systems, this provider can play audio in breathtaking 6.1 surround sound, allowing real (non-simulated) 3D sound positioning. The SRS Miles Encoder is also based on the Miles API which makes it extremely fast! The Miles SRS Circle Surround provider is accessed by passing MSS_MC_SRS_CIRCLE_SURROUND as the channel specification in a call to AIL_open_digital_driver or AIL_quick_startup.

Note that using the SRS Miles Encoder does not give you the right to use the SRS Circle Surround Logo. To use this, you must become an SRS licensee (the criteria to do this are listed below).

Overview of SRS Circle Surround

SRS Circle Surround encoding provides the capability to encode up to 6.1 channels of audio for transmission or storage over two output channels or standard two-channel carriers. This represents a substantial improvement over previous Lt/Rt based encoding systems, which are not as well suited to handle modern, multichannel media with more than four channels of audio. Circle Surround encoding is backward compatible with all matrix decoders, such as Dolby Pro Logic and Dolby Pro Logic II, with playback performance subject to the limitations of the specific decoder.

For linear tracks, a Circle Surround Encoder, model CSE-07, and Circle Surround Decoder, model number CSD-07, are used. There are also plug-ins available for those users of VST and TDM based sytems. These include the SRS Circle Surround TDM Pro, model number TDM-02, and the SRS Circle Surround VST Pro, model number VST-02.

On Becoming an SRS Labs, Inc. Licensee

In order to become an SRS Circle Surround Licensee, which grants you the right to use the SRS Circle Surround Logo, four basic criteria need to be met:

I. You must use an SRS-approved, real-time encoding scheme, such as the Miles SRS Circle Surround 6.1 Encoder.

II. You must request the necessary trademarks from SRS Labs, Inc.

III. You must sign a royalty-free License and Trademark Usage Agreement, which grants a license to use the SRS Circle Surround Trademark, subject to these conditions.

IV. You must send a sample of the finished title prior to the time of release.

For more information on becoming a Surround licensee, or to request a licensing agreement, please contact SRS Labs directly:

SRS Labs Inc.
2909 Daimler Street
Santa Ana, CA 92705
949-442-1070

www.srslabs.com website

For more information on producing in SRS Circle Surround, please visit the SRS web site.

For technical questions on producing content in Circle Surround, please e-mail support@srsproaudio.com here.

To request a licensing agreement via email, please email SRS's game licensing department.

Related Sections: Miles SRS Circle Surround Provider
Related Functions: AIL_open_digital_driver, AIL_quick_startup


Miles Dolby Surround Provider

Discussion

The Miles Dolby Surround provider is accessed by passing MSS_MC_DOLBY_SURROUND as the channel specification in a call to AIL_open_digital_driver or AIL_quick_startup. It is a run-time surround sound encoder, implemented in a so-called 'matrix' output filter. Using multi-speaker systems like those from Cambridge Soundworks, Boston Acoustics, and Altec Lansing (or any other surround sound system), the Dolby Surround provider can steer audio to the rear speakers - allowing real (non-simulated) 3D sound positioning.

Note that using the Miles Dolby Surround matrix filter does not give you the right to use the Dolby Logo. To use the Dolby logo, you must become a Dolby Surround licensee (the criteria to do this are listed below).

Overview of Dolby Surround

A Dolby Surround soundtrack carries four audio channels (left, center, right, and surround) in a two-channel stereo format. Creating a Dolby Surround soundtrack involves mixing down these four audio channels and encoding then into a final stereo mix using a Dolby Surround encoder (like the run-time version built into Miles). For linear tracks, a Dolby Surround encoder, model SEU-4, and Dolby Surround decoder, model SDU-4, are used. There is also a plug-in available for users of Digidesign's Pro Tools system.

For sound effects which need to be positioned on the fly, you should use the Miles Dolby Surround matrix filter.

On Becoming a Dolby Surround Licensee

In order to become a Dolby Surround Licensee, which grants you the right to use the Dolby Surround Logo, four basic criteria need to be met:

I. You must use a Dolby-approved, real-time encoding scheme, such as the Miles Dolby Surround provider.

II. You must use a Dolby-approved Surround facility to encode the linear audio in your game.

III. You must sign a royalty-free trademark agreement, which grants a license to use the Dolby Surround trademark, subject to these conditions.

IV. You must send a sample of the finished title at, or prior to, the time of release.

For more information on becoming a Surround licensee, or to request a licensing agreement, please contact Dolby directly:

Dolby Laboratories, Inc.
Encoding Services Department
100 Potrero Ave.
San Francisco, CA 94103-4813
Tel: 415-558-0200
Fax: 415-863-1373

For more information on producing in Dolby Surround, please visit the Dolby web-site.

For technical questions on producing content in Dolby Surround, please E-mail.

To request a licensing agreement via email, please E-mail.

Related Sections: Miles Dolby Surround Provider
Related Functions: AIL_open_digital_driver, AIL_quick_startup


Miles DTS Provider for the Sony PS2

Discussion

The Miles DTS provider is accessed by passing MSS_MC_40_DTS or MSS_MC_51_DTS as the channel specification in a call to AIL_open_digital_driver or AIL_quick_startup. Miles's DTS support is provided by a run-time surround-sound encoder module which is implemented in a so-called 'matrix' output filter.

To add DTS support to your Sony PS2 application, you'll need to link with the mssdts.a library provided with the MSS distribution, and also with the libidtsenc.a library obtained directly from DTS.

You'll need to call Register_RIB(DTS) prior to AIL_startup, and you'll also need to pass the RAD_IOP_NEED_CORE0 + RAD_IOP_SPDIF flags to both RAD_IOPMemoryAmount and RAD_IOPStartUp. That's all there is to it! However, for best CPU performance, we also recommend that you allow Miles access to the PS2 scratchpad RAM when using DTS. You can do this by calling AIL_set_scratchpad_policy at any time.

VU0 Usage

The DTS encoder heavily utilizes VU0 (Vector Unit 0) in macro mode. Registers VF01 through VF31 and the ACC register, as well as the MAC and Status flags, are all used by the DTS encoder at interrupt time. MSS saves and restores these registers, so your application should not normally be affected.

If any VU0 code is executing in micro mode when an MSS mixer service interrupt occurs, the DTS encoder will stall until the micro mode routine has finished executing. Any code or data in local VU0 memory is not affected by the encoder.

Switching between PCM and DTS

According to DTS, when switching the digital output from PCM to DTS or DTS to PCM, it is necessary to produce 2 seconds of silent PCM or DTS data after the switch occurs. Otherwise the switch may not work correctly on some receivers. In practice, since the Miles DTS encoder begins generating a silent bitstream as soon as AIL_open_digital_driver is called, this guideline can be met by refraining from playing any sounds for two seconds after opening the driver.

DTS Preference Control

The Miles DTS module doesn't provide any output-filter properties or properties. If your application is tight on memory, you can control the encoding quality by setting a lower value for the DIG_ENCODE_QUALITY_PERCENT preference before calling AIL_open_digital_driver. This property can range from 0 to 100, and defaults to 50.

Licensing info Miles ships with everything necessary to hook up to DTS, except for the DTS library itself. The DTS library is only available directly from DTS. To obtain it (and we definitely recommend doing so - it sounds great!), just drop an email to Mitch Soule at mitchs@radgametools.com and he can hook you up with the DTS folks.

Related Sections: Miles DTS Provider for the Sony PS2
Related Functions: AIL_open_digital_driver, AIL_quick_startup, AIL_set_scratchpad_policy, AIL_startup, RAD_IOPMemoryAmount, RAD_IOPStartUp
Related Basic Types: MILES_PREFERENCES, MSS_MC_SPEC


Digital Audio Input (Recording) Services

Discussion

The Digital Audio Input Services allow you to capture input coming in from a microphone.

Digital Audio Input (Recording) Services
AIL_open_input | opens a digital input channel (usually from the microphone) to receive input digital audio data.
AIL_INPUT_INFO | specifies the details for performing digital input.
AIL_input_callback | specifies a user callback that is called as audio data is received by the input device.
AIL_close_input | closes a digital input handle.
AIL_set_input_state | controls whether the digital input channel is actively recording or not.
AIL_get_input_info | returns the information structure used to open the digital input channel.


AIL_open_input

The function AIL_open_input opens a digital input channel (usually from the microphone) to receive input digital audio data.

HDIGINPUT AIL_open_input(
  AIL_INPUT_INFO *info
);

Out Parameters

info
points to a structure of type AIL_INPUT_INFO. The info structure contains the details of the digital audio input to perform.

Returns

A handle to the new input handle, or NULL if the open failed.

Discussion

The Miles Sound System uses the waveIn API for input.

Recording doesn't begin until you call the AIL_set_input_state function.

There are two types of sound drivers under Windows - half-duplex and full-duplex. Half-duplex means that you can either play audio or record audio, but not at the same time. Full-duplex means that you can play and record audio simultaneously. There are virtually no sound cards available any more that don't have full-duplex drivers available (although they sometimes must be switched to full-duplex in the Control Panel), so you will usually just want to require full-duplex drivers.

If, however, you want to support half-duplex driver, then you must use switch between playing and recording using logic somewhat like this:

To record audio: call AIL_digital_handle_release, call AIL_open_input, start recording.

To play audio again: call AIL_close_input, call AIL_digital_handle_reacquire, starting playing again.

On MacOS, recording is always perform in full-duplex mode. You should select a device in "Sound Monitoring" pop-up in the "Monitor and Sound" control panel.

Group: Digital Audio Input (Recording) Services
Related Functions: AIL_close_input, AIL_digital_handle_reacquire, AIL_digital_handle_release, AIL_get_input_info, AIL_open_input, AIL_set_input_state
Related Basic Types: HDIGINPUT, MSS_PLATFORM_PROPERTY
Related Structures: AIL_INPUT_INFO


AIL_INPUT_INFO

The structure AIL_INPUT_INFO specifies the details for performing digital input.

struct AIL_INPUT_INFO
{
  S32 device_ID;
  U32 hardware_format;
  S32 hardware_rate;
  S32 buffer_size;
  UINTa user_data;
  AIL_input_callback callback;
};

In Members

device_ID
waveIn device ID or WAVE_MAPPER for the Control Panel input setting on Windows. Zero on MacOS.
hardware_format
requested input sound format - use one of the MILES_DIGITAL_FORMAT constants.
hardware_rate
requested input sound rate (usually 8000, 11025, 22050, or 44100).
buffer_size
exact amount of data in bytes to be returned to the callback in each call.
user_data
the value that will be passed to the callback function as the user parameter.
callback
callback to call as the sound data is received by the input device.

Group: Digital Audio Input (Recording) Services
Related Functions: AIL_get_input_info, AIL_input_callback, AIL_open_input
Related Basic Types: MILES_DIGITAL_FORMAT, S32, U32, UINTa


AIL_input_callback

The function AIL_input_callback specifies a user callback that is called as audio data is received by the input device.

void AILCALLBACK AIL_input_callback(
  void const * data,
  S32 bytes,
  UINTa user_data
);

In Parameters

data
points to a buffer containing the audio data.
bytes
specifies the length in bytes of the audio buffer.
user_data
specifies the user_data value from the input structure.

Discussion

This function is called back from Miles as digital audio is received from the input device.

Group: Digital Audio Input (Recording) Services
Related Basic Types: S32, UINTa, void, void const *
Related Structures: AIL_INPUT_INFO


AIL_close_input

The function AIL_close_input closes a digital input handle.

void AIL_close_input(
  HDIGINPUT input
);

In Parameters

input
gives the input handle to close.

Discussion

Use this function to close an input handle that you opened with AIL_open_input.

Use this function before reacquiring the digital output handle when running on half-duplex cards.

Group: Digital Audio Input (Recording) Services
Related Functions: AIL_open_input
Related Basic Types: HDIGINPUT, void


AIL_set_input_state

The function AIL_set_input_state controls whether the digital input channel is actively recording or not.

S32 AIL_set_input_state(
  HDIGINPUT input,
  S32 enable
);

In Parameters

input
gives the input handle to control.
enable
tells Miles whether to begin recording (non-zero) or stop recording (zero).

Returns

Non-zero if recording was successfully enabled, zero if recording is disabled (or couldn't be enabled).

Discussion

After opening, a Miles digital input handle won't start recording until this function is called.

Group: Digital Audio Input (Recording) Services
Related Functions: AIL_open_input
Related Basic Types: HDIGINPUT, S32


AIL_get_input_info

The function AIL_get_input_info returns the information structure used to open the digital input channel.

AIL_INPUT_INFO * AIL_get_input_info(
  HDIGINPUT input
);

In Parameters

input
gives the input handle to query.

Returns

Returns the AIL_INPUT_INFO structure passed to AIL_open_input.

Group: Digital Audio Input (Recording) Services
Related Functions: AIL_open_input
Related Basic Types: HDIGINPUT
Related Structures: AIL_INPUT_INFO


Digital Audio Streaming Services

Discussion

The Digital Audio Streaming Services allow you to quickly and easily stream an audio file out of a disk file. When streaming, only a small bit of the file is ever in memory at one time.

Digital Audio Streaming Services
AIL_open_stream | opens a stream handle based on a supported file (.WAV, Ogg Vorbis, XMA, or MP3, and others).
AIL_close_stream | closes a stream handle.
AIL_service_stream | services the given stream handle.
AIL_auto_service_stream | turns auto-servicing on or off for a stream handle (it's turned on by default).
AIL_start_stream | starts playback of the specified stream.
AIL_pause_stream | pauses the playback of the specified stream handle.
AIL_stream_sample_handle | returns the underlying HSAMPLE associated with a given HSTREAM instance.
AIL_set_stream_loop_count | arranges for a stream to be restarted immediately upon completion, for a total of two or more iterations.
AIL_stream_loop_count | returns the number of loop iterations remaining for the given stream.
AIL_set_stream_loop_block | arranges for a sub-block of a stream to be looped.
AIL_set_stream_position | adjusts the playback position of a stream.
AIL_stream_position | reports the current playback position of a stream.
AIL_set_stream_ms_position | adjusts the playback position of a stream.
AIL_stream_ms_position | reports the total length and the current playback position of a stream.
AIL_stream_status | returns the status of a given stream handle.
AIL_set_stream_user_data | sets a value for one of eight user data entries associated with each stream handle.
AIL_stream_user_data | retrieves a value for one of eight user data entries associated with each stream handle.
AIL_stream_info | returns information about the given stream handle.
AIL_register_stream_callback | arranges for callback service to be provided to an application function immediately upon reaching the end of a stream.
AILSTREAMCB | specifies a user-defined digital audio stream callback.


AIL_open_stream

The function AIL_open_stream opens a stream handle based on a supported file (.WAV, Ogg Vorbis, XMA, or MP3, and others).

HSTREAM AIL_open_stream(
  HDIGDRIVER dig,
  char const * name,
  S32 stream_mem
);

In Parameters

dig
specifies the digital driver handle to use.
name
specifies the name of the file to stream. The streaming API supports .WAV, Ogg Vorbis, XMA, and MP3 files, among other possible formats.
stream_mem
specifies the amount of memory to use for streaming. Normally, you will pass a zero for this parameter which tells MSS to determine the optimal amount of memory to use. You may want to increase this parameter if you plan on increasing the playback rate.

Returns

A handle to the new stream, or NULL if the open failed.

Discussion

Currently-supported file types include uncompressed .WAV files, IMA ADPCM compressed .WAV files, Xbox 360 XMA-compressed .WAV files, Ogg Vorbis files (mono, stereo, and multichannel), .WAV-wrapped MP3 files, standard MP3 files, and Xbox ADPCM wave files. A stream is similar to a digital sample, but instead of the entire file being loaded into memory, only a small portion of the file is loaded at once.

To stream data files that are embedded within other packed files or libraries, you can mark up the filename to tell MSS how to access it. Simply use a filename string of the form

                *my_large_packed_file.pak*3141592*271828.mp3

to access (for example) a 3,141,592-byte .mp3 file that resides within a container file at byte offset 271,828. When creating a subfile descriptor string, only the suffix portion of the original filename (.mp3 in this case) is needed.

It's also possible to force MSS to use an existing open file handle supplied by your application, but this method is platform-specific and very error prone. Email RAD Game Tools for help with this feature if you really need it, but be aware that it's been deprecated and will not be supported in future versions of MSS.

On the Playstation 2, you can also stream audio from IOP or SPU memory using this function. To load from IOP memory, you can create a special file handle to use with the RAD_IOPGetFileHandleToIOPMemory macro. To load from SPU memory, you use the RAD_IOPGetFileHandleToIOPMemory macro. For example, to play 32768 bytes at IOP memory address 0x12340, you'd do something like:

char load_handle[ 32 ];
sprintf( load_handle, "\\\\\\\\%d,32768", RAD_IOPGetFileHandleToIOPMemory( 0x12340 ) );
stream = AIL_open_stream( load_handle, 0, 0 );

Of course, you can also override the I/O functions that Miles uses to read from the stream with the AIL_set_file_callbacks function, if you don't want to bother composing a subfile descriptor or using the (deprecated) ASCII-encoded file handle technique. On platforms that support asynchronous file access, you should also call AIL_set_file_async_callbacks. Note, however, that most applications are better off letting Miles do its own file access, even with packed files that your application has already opened. Unless you have a very specific reason for overriding Miles's file I/O calls, we recommend against doing so.

Under Windows, streams are automatically serviced in the background by default. You can service the buffers manually with the AIL_service_stream and AIL_auto_service_stream functions.

Under MacOS 9, Wii and PS2, streams are automatically serviced with background asynchronous reads.

Under DOS, you must always service the stream manually with the AIL_service_stream function.

If the total size of the streaming buffers is greater than or equal to the total stream size, then the MSS will preload all of the data automatically, so you'll never use more memory than a normal sample would take.

This function doesn't actually load any of the streaming buffers - the only routine in the streaming API that performs the file reading is AIL_service_stream.

Under DOS, Wii, PS2 and MacOS 9, this function must not be invoked from an interrupt-based callback function.

Monaural-source streams may be steered to multiple output speakers via AIL_stream_sample_handle and the various volume/pan and channel-level control functions. Additionally, multichannel (> 2-channel) Ogg Vorbis files may be streamed with full channel/speaker routing capabilities via AIL_set_sample_channel_levels. Consult the How do I use multi-channel sound output in Miles? FAQ for an overview of multichannel audio support.

Example files that use this function: Demo.C, Streamer.C, FileHndl.C

Group: Digital Audio Streaming Services
Related Sections: Memory management under PlayStation 2
Related Functions: AIL_auto_service_stream, AIL_close_stream, AIL_register_stream_callback, AIL_service_stream, AIL_set_file_async_callbacks, AIL_set_file_callbacks, AIL_set_sample_channel_levels, AIL_set_stream_loop_count, AIL_stream_sample_handle, RAD_IOPGetFileHandleToIOPMemory
Related Basic Types: HDIGDRIVER, HSTREAM, S32, char const *
Related FAQs: How do I access files from a big packed file?, How do I stream a file off a hard disk or CD?, How do I use multi-channel sound output in Miles?, On the Sony PS2, how can I use the IOP or SPU memory to hold my audio?


AIL_close_stream

The function AIL_close_stream closes a stream handle.

void AIL_close_stream(
  HSTREAM stream
);

In Parameters

stream
specifies the stream handle to close.

Discussion

This function closes the file handle and frees all of the internal memory.

Under DOS, Wii, PS2 and MacOS 9, this function must not be invoked from an interrupt-based callback function.

Example files that use this function: Demo.C, Streamer.C

Group: Digital Audio Streaming Services
Related Functions: AIL_open_stream
Related Basic Types: HSTREAM, void


AIL_service_stream

The function AIL_service_stream services the given stream handle.

S32 AIL_service_stream(
  HSTREAM stream,
  S32 fillup
);

In Parameters

stream
specifies which stream to service.
fillup
specifies whether MSS should fill all of its input buffers. If you have a CPU-intensive task to perform, passing a non-zero value can help avoid sound drop-outs. Normally, however, just pass in zero (don't fill).

Returns

The total number of bytes read during the call.

Discussion

This function should normally only be necessary under DOS - Windows and MacOS application will usually use auto-streaming. You should try to call this function at least 10 times per second to avoid sound drop-outs.

Under DOS and MacOS 9, this function must not be invoked from an interrupt-based callback function.

Example files that use this function: Demo.C, Streamer.C

Group: Digital Audio Streaming Services
Related Sections: Sharing the CPU under DOS
Related Functions: AIL_auto_service_stream, AIL_open_stream, AIL_serve, AIL_start_stream
Related Basic Types: HSTREAM, S32


AIL_auto_service_stream

The function AIL_auto_service_stream turns auto-servicing on or off for a stream handle (it's turned on by default).

void AIL_auto_service_stream(
  HSTREAM stream,
  S32 onoff
);

In Parameters

stream
specifies which stream handle to control.
onoff
specifies whether to turn auto-servicing on (non-zero) or off (zero).

Discussion

Auto-servicing is available under Windows, Xbox, Wii, PS2 and MacOS - DOS applications must call AIL_service_stream manually.

Under Win32 and Win64, auto-streaming is accomplished with a secondary thread, so you don't need to call PeekMessage.

The only real reason you should ever have to turn off auto-streaming is if you want exact control of when file reading should take place.

Under DOS and MacOS 9, this function must not be invoked from an interrupt-based callback function.

Group: Digital Audio Streaming Services
Related Functions: AIL_open_stream, AIL_serve, AIL_service_stream
Related Basic Types: HSTREAM, S32, void


AIL_start_stream

The function AIL_start_stream starts playback of the specified stream.

void AIL_start_stream(
  HSTREAM stream
);

In Parameters

stream
specifies which stream to begin playing.

Discussion

This function doesn't do any file reading, so it is safe to call from an interrupt-based callback function.

If you call this function on an already-playing stream, then the stream will be restarted from the beginning.

Under DOS, you must call AIL_service_stream for the stream to be played.

Example files that use this function: Demo.C, Streamer.C

Group: Digital Audio Streaming Services
Related Functions: AIL_pause_stream, AIL_service_stream, AIL_stream_status
Related Basic Types: HSTREAM, void
Related FAQs: How do I start an audio file somewhere in the middle?, How do I stream a file off a hard disk or CD?


AIL_pause_stream

The function AIL_pause_stream pauses the playback of the specified stream handle.

void AIL_pause_stream(
  HSTREAM stream,
  S32 onoff
);

In Parameters

stream
specifies stream to control.
onoff
tells MSS to pause (non-zero) or resume (zero) the playback.

Discussion

The AIL_start_stream function will also resume playback (but at the beginning of the stream).

Example files that use this function: Demo.C, Streamer.C

Group: Digital Audio Streaming Services
Related Functions: AIL_set_stream_loop_count, AIL_start_stream, AIL_stream_status
Related Basic Types: HSTREAM, S32, void
Related FAQs: How do I start an audio file somewhere in the middle?


AIL_stream_sample_handle

The function AIL_stream_sample_handle returns the underlying HSAMPLE associated with a given HSTREAM instance.

HSAMPLE AIL_stream_sample_handle(
  HSTREAM stream
);

In Parameters

stream
indicates the stream whose HSAMPLE should be returned.

Returns

The HSAMPLE used by the stream object to render its digital audio.

Discussion

In MSS 7, a number of redundant functions were replaced with this accessor function. If your application previously called AIL_set_stream_reverb_levels, AIL_stream_get_reverb_levels, AIL_stream_processor, AIL_set_stream_processor, AIL_stream_playback_rate, AIL_set_stream_playback_rate, AIL_set_stream_low_pass_cut_off, AIL_stream_low_pass_cut_off, AIL_set_stream_volume_pan, AIL_stream_volume_pan, or AIL_filter_stream_property, it should be modified to call the HSAMPLE-based version of those functions after obtaining the stream's underlying HSAMPLE via AIL_stream_sample_handle.

Group: Digital Audio Streaming Services
Related Functions: AIL_open_stream, AIL_stream_sample_handle
Related Basic Types: HSAMPLE, HSTREAM
Related FAQs: How do I apply a low-pass filter?, I used an older version of Miles and now my volume and pan calls are weird - what's going on? And what's with the two types of volume functions?, What's the best way to port my older Miles application to MSS 7?


AIL_set_stream_loop_count

The function AIL_set_stream_loop_count arranges for a stream to be restarted immediately upon completion, for a total of two or more iterations.

void AIL_set_stream_loop_count(
  HSTREAM stream,
  S32 loop_count
);

In Parameters

stream
indicates the stream to loop.
loop_count
should be set to the desired number of iterations.

Discussion

A loop_count value of 1 results in a single iteration, with no looping. This is the default loop count value, as initialized by AIL_open_stream.

A loop_count value of 0 creates an infinite loop, which can be interrupted by calling AIL_pause_stream or by calling AIL_set_stream_loop_count to establish a different loop count.

loop_count values of 2 or more cause the stream to be played a total of 2 or more times. The current number of iterations remaining may be monitored with AIL_stream_loop_count.

Group: Digital Audio Streaming Services
Related Functions: AIL_open_stream, AIL_pause_stream, AIL_set_sample_loop_count, AIL_set_stream_loop_block, AIL_set_stream_loop_count, AIL_stream_loop_count
Related Basic Types: HSTREAM, S32, void
Related FAQs: I'm getting a glitch when I loop an MP3 or ADPCM file - what can I do?, What MP3 encoder should I use?


AIL_stream_loop_count

The function AIL_stream_loop_count returns the number of loop iterations remaining for the given stream.

S32 AIL_stream_loop_count(
  HSTREAM stream
);

In Parameters

stream
indicates the stream handle whose current loop count is to be returned.

Returns

The stream's current loop count. A value of 0 means that the stream is looping indefinitely, while a value of 1 means that the stream is on its last iteration, or is not looping at all.

Discussion

See AIL_set_stream_loop_count for more information.

Group: Digital Audio Streaming Services
Related Functions: AIL_set_stream_loop_count
Related Basic Types: HSTREAM, S32


AIL_set_stream_loop_block

The function AIL_set_stream_loop_block arranges for a sub-block of a stream to be looped.

void AIL_set_stream_loop_block(
  HSTREAM stream,
  S32 loop_start_offset,
  S32 loop_end_offset
);

In Parameters

stream
indicates the stream to loop.
loop_start_offset
should be set to the offset of where looping should begin. If the stream is compressed, this offset is specified in "compressed" bytes.
loop_end_offset
should be set to the offset of where looping should end. If the stream is compressed, this offset is specified in "compressed" bytes.

Discussion

By default, looping a sound will loop the entire stream. This function allows you to loop a smaller sub-section of the stream.

If the stream data is compressed, then the offset passed to this function is in "compressed" bytes.

A value of zero for loop_start_offset indicates the beginning of the stream, and a value of -1 for loop_end_offset indicates the end of the stream, regardless of its actual length.

Group: Digital Audio Streaming Services
Related Functions: AIL_set_sample_loop_block, AIL_set_stream_loop_count
Related Basic Types: HSTREAM, S32, void
Related FAQs: I'm getting a glitch when I loop an MP3 or ADPCM file - what can I do?, What MP3 encoder should I use?


AIL_set_stream_position

The function AIL_set_stream_position adjusts the playback position of a stream.

void AIL_set_stream_position(
  HSTREAM stream,
  S32 pos
);

In Parameters

stream
indicates the stream whose position is to be adjusted.
pos
indicates the offset in bytes of the new playback position from the beginning of the stream. If the stream is compressed, this offset is specified in "compressed" bytes.

Discussion

By means of this function, it is possible to instantaneously change the location from which stream data is being played. The change will take effect as soon as the next block of audio data from the sample is merged into the hardware buffer.

If the stream data is compressed, then the offset passed to this function is in "compressed" bytes.

You can position based on milliseconds with the AIL_set_stream_ms_position function.

Group: Digital Audio Streaming Services
Related Functions: AIL_set_sample_loop_block, AIL_set_sample_position, AIL_set_stream_ms_position, AIL_stream_position
Related Basic Types: HSTREAM, S32, void
Related FAQs: I'm getting a glitch when I loop an MP3 or ADPCM file - what can I do?


AIL_stream_position

The function AIL_stream_position reports the current playback position of a stream.

S32 AIL_stream_position(
  HSTREAM stream
);

In Parameters

stream
indicates the stream whose playback position is to be reported.

Returns

The offset in bytes of the next sample point to be fetched, relative to the beginning of the stream.

Discussion

The granularity of the reported position offset depends on the hardware buffer latency, but it will always reflect an address which has not yet been reached by the playback mechanism.

The Miles Sound System digital audio mixer operates on the application's audio data in small chunks, called blocks. Part of the system's responsibility is to poll the hardware buffers in the background to determine when the next block of audio data from the application should be processed and copied into an empty hardware half-buffer. As an example, consider a hardware driver which is configured to play 16-bit audio at 20,000 Hz with a pair of 1,000-byte half-buffers. The driver's data rate is 40,000 bytes per second, implying a half-buffer playback rate of 40,000 / 1,000, or 40 buffer transitions per second.

At a rate of 40 times per second, then, a sample block equivalent to one half-buffer's worth of data is fetched from the application's sample data buffer at the current playback position. The samples are resampled if necessary to conform to the driver's hardware rate, converted between 8-bit and 16-bit formats where appropriate, mathematically scaled for volume and panpot control, algebraically added to data from other active samples, clipped, and copied into the driver's empty half-buffer to be played as soon as the other half-buffer finishes playing.

AIL_stream_position reports the location of the beginning of the next application data block to be fetched and processed by this mechanism.

Example files that use this function: Streamer.C

Group: Digital Audio Streaming Services
Related Functions: AIL_set_stream_position, AIL_stream_ms_position, AIL_stream_position
Related Basic Types: HSTREAM, S32


AIL_set_stream_ms_position

The function AIL_set_stream_ms_position adjusts the playback position of a stream.

void AIL_set_stream_ms_position(
  HSTREAM stream,
  S32 milliseconds
);

In Parameters

stream
indicates the sample whose position is to be adjusted.
milliseconds
indicates the offset in milliseconds of the new playback position from the beginning of the stream.

Discussion

By means of this function, it is possible to instantaneously change the location from which stream data is being played. The change will take effect as soon as the next block of audio data from the sample is merged into the hardware buffer.

Group: Digital Audio Streaming Services
Related Functions: AIL_set_stream_position, AIL_stream_ms_position
Related Basic Types: HSTREAM, S32, void


AIL_stream_ms_position

The function AIL_stream_ms_position reports the total length and the current playback position of a stream.

void AIL_stream_ms_position(
  HSTREAM stream,
  S32 *total_milliseconds,
  S32 *current_milliseconds
);

In Parameters

stream
indicates the stream whose position information is to be reported.

Out Parameters

total_milliseconds
is the address to place the total length of the stream into. If you don't need the total length, pass a NULL for this parameter.
current_milliseconds
is the address to place the current millisecond position into. This value increases as the sample is played. If you don't need the current position, pass a NULL for this parameter.

Group: Digital Audio Streaming Services
Related Functions: AIL_set_stream_ms_position, AIL_stream_position
Related Basic Types: HSTREAM, S32, void


AIL_stream_status

The function AIL_stream_status returns the status of a given stream handle.

S32 AIL_stream_status(
  HSTREAM stream
);

In Parameters

stream
indicates the stream handle for which the status is to be returned.

Returns

One of the MILES_DIGITAL_STATUS constants.

Group: Digital Audio Streaming Services
Related Functions: AIL_pause_stream, AIL_start_stream
Related Basic Types: HSTREAM, MILES_DIGITAL_STATUS, S32


AIL_set_stream_user_data

The function AIL_set_stream_user_data sets a value for one of eight user data entries associated with each stream handle.

void AIL_set_stream_user_data(
  HSTREAM stream,
  U32 index,
  SINTa value
);

In Parameters

stream
indicates the stream for which a user data entry value is to be set.
index
is a number from 0 to 7, indicating which user data entry is to be set.
value
is the user data value to set.

Discussion

Stream user data entries are provided to assist application programs in keeping track of its allocated stream handles. They are especially useful for communicating with the callback function to which only stream handles are passed, without resorting to the use of global variables.

The MSS system never alters or initializes user data values under any circumstances.

Group: Digital Audio Streaming Services
Related Functions: AIL_stream_user_data
Related Basic Types: HSTREAM, SINTa, U32, void


AIL_stream_user_data

The function AIL_stream_user_data retrieves a value for one of eight user data entries associated with each stream handle.

SINTa AIL_stream_user_data(
  HSTREAM stream,
  U32 index
);

In Parameters

stream
indicates the stream for which a user data entry value is to be retrieved.
index
is a number from 0 to 7, indicating which user data entry value is to be retrieved.

Returns

The value which was previously stored at user data entry index.

Discussion

Stream user data entries are provided to assist application programs in keeping track of its allocated stream handles. They are especially useful for communicating with the callback function to which only stream handles are passed, without resorting to the use of global variables.

The MSS system never alters or initializes user data values under any circumstances.

Group: Digital Audio Streaming Services
Related Functions: AIL_set_stream_user_data
Related Basic Types: HSTREAM, SINTa, U32


AIL_stream_info

The function AIL_stream_info returns information about the given stream handle.

void AIL_stream_info(
  HSTREAM stream,
  S32 *datarate,
  S32 *type,
  S32 *length,
  S32 *memory
);

In Parameters

stream
specifies the stream handle that you are requesting information about.

Out Parameters

datarate
returns the original data rate of the streaming file.
type
returns the type of sound in the streaming file. See AIL_init_sample for more information.
length
returns the total length of the streaming file in bytes.
memory
returns the total amount RAM being used for the streaming file.

Discussion

Example files that use this function: Streamer.C

Group: Digital Audio Streaming Services
Related Functions: AIL_init_sample
Related Basic Types: HSTREAM, S32, void


AIL_register_stream_callback

The function AIL_register_stream_callback arranges for callback service to be provided to an application function immediately upon reaching the end of a stream.

AILSTREAMCB AIL_register_stream_callback(
  HSTREAM stream,
  AILSTREAMCB callback
);

In Parameters

stream
indicates the stream for which end of stream callback service is desired.
callback
should be set to the address of the callback function which is to be invoked just after the last audio data block in a sample is merged into the hardware buffer for playback. A value of NULL cancels end-of-sample callbacks.

Returns

The address of the previously-installed end of stream callback function handler.

Discussion

Most MSS functions can be safely invoked from within callback functions. Exceptions include driver-installation or driver-shutdown functions and any other functions which may perform OS or BIOS calls, such as AIL_open_stream. These exceptions are noted in the descriptions of the functions involved. If in doubt about whether a particular action may safely be performed from within a callback function, contact RAD Game Tools for assistance.

Group: Digital Audio Streaming Services
Related Functions: AILSTREAMCB, AIL_open_stream
Related Basic Types: HSTREAM
Related FAQs: What's the deal with callbacks - are they threads, interrupts, system timers, or what?


AILSTREAMCB

The function AILSTREAMCB specifies a user-defined digital audio stream callback.

void AILCALLBACK AILSTREAMCB(
  HSTREAM stream
);

In Parameters

stream
indicates the stream handle that generated the callback.

Discussion

This callback type is made by registering with the AIL_register_stream_callback function.

Group: Digital Audio Streaming Services
Related Functions: AIL_register_stream_callback
Related Basic Types: HSTREAM, void


Digital Filter Services

Discussion

Filter processors are external plug-ins that can manipulate digital sample data. Common filter processors include equalizers, low or high-pass filters, and chorus/flanging filters. Under Windows, filter processors themselves are simply Win32 or Win64 DLLs that have the "FLT" file extension. Under MacOS, filter processors are shared libraries. At startup time, MSS loads any filters found in the same directory as the MSS32.DLL file (or a directory specified by AIL_set_redist_directory).

On platforms that can't use Win32 DLLs, your application must enable filter support by calling Register_RIB(DSP) prior to calling AIL_startup. Note that software DSP filters may be unsuitable for performance-critical applications on the original Xbox. The original Xbox has specific dedicated DSP hardware that you may wish to use instead. See the Xbox docs for details.

Miles currently includes thirteen different external filter modules. They include: capture, high-pass, band-pass, parametric equalizer, shelving equalizer, delay, resonator, phaser, chorus, flange, ring/amplitude modulator, compressor, and a volume ramper. Miles also includes low-pass and high-quality reverb filtering built right into our software mixer.

As with all of Miles, we include full source code for all of the filters (see the \src\sdk directory).

By default, filter processors are not installed on any digital driver. To install a filter processor to be the default filter processor for a digital driver, use the AIL_set_digital_driver_processor function. To install a filter processor for a specific sample (which is by far the more-common application), use the AIL_set_sample_processor function. Each individual sample can have up to eight sample processors installed at one time. Filters and samples can be mixed and matched at will -- you could have a compressor filter on one sample and a low-pass filter on another, for instance.

Filter processors can contain both provide-level and sample-level settings. A provider-level setting might be the amount of memory it should use. A sample-level setting might be the mix level to use for a given HSAMPLE. As with all RIB-based plug-ins, you read and change the settings through the use of "properties".

The MULTIFLT.CPP and FILTER.CPP example programs are a great way to come up to speed on MSS's audio-filtering capabilities.

Digital Filter Services
AIL_set_redist_directory | sets the location of your application's Miles directory.
AIL_startup | initializes the Miles Sound System and prepares for the installation and use of sound drivers.
AIL_find_filter | tries to locate a filter by its name.
AIL_enumerate_filters | enumerates the available filter processors for display or for opening.
AIL_open_filter | opens a filter to prepare it for use.
AIL_close_filter | closes a previously opened filter.
AIL_set_sample_processor | assigns the filter or mixer stages for a specific sample.
AIL_sample_processor | returns the current filter or mixer stage provider for a specific sample.
AIL_digital_driver_processor | returns the current default filter or mixer stage provider for a specific driver.
AIL_digital_output_filter | returns the output filter (either per-voice or matrix) provider for a specific driver.
SAMPLESTAGE | describes the stage in the sample pipeline to install the filter on.
AIL_set_digital_driver_processor | assigns the default filter or mixer stages for a digital driver.
DIGDRVSTAGE | describes the stage in the driver pipeline to install the filter on.
AIL_enumerate_filter_properties | enumerates a filter's provider-level properties.
RIB_INTERFACE_ENTRY | specifies a structure that contains RIB property information.
RIB_ENTRY_TYPE | describes the type of the RIB entry.
RIB_DATA_SUBTYPE | describes the variable type of the RIB entry.
AIL_enumerate_filter_sample_properties | enumerates the possible sample-level filter properties.
AIL_enumerate_sample_stage_properties | enumerates the possible sample-level filter properties for the filter currently assigned to a given HSAMPLE processing stage.
AIL_filter_property | retrieves and/or sets the current value of the specified provider-level property.
AIL_sample_stage_property | retrieves and/or sets the current value of the specified sample-level property.
Capture Filter
Low-Pass Filter
EAX Compatible Reverb
High-Pass Filter
Band-Pass Filter
All-Pass Filter
Resonator Filter
Delay Filter
Parametric Equalizer Filter
Shelving Equalizer Filter
Compressor Filter
Gain Block Filter
Volume Ramp Filter
Ring-Amplitude Modulator Filter
Phaser Filter
Chorus Filter
Flange Filter


AIL_find_filter

The function AIL_find_filter tries to locate a filter by its name.

S32 AIL_find_filter(
  char * name,
  HPROVIDER *found
);

In Parameters

name
contains the name of the filter to search for.

Out Parameters

found
contains the found provider if the filter name was located.

Returns

0 if no filter was found; non-zero if a filter was found.

Discussion

You can call this function before AIL_open_filter or AIL_set_sample_processor to locate a specific filter to use. You can enumerate all of the filters with the AIL_enumerate_filters function.

The HPROVIDER handle values returned by this function can change from one program execution to the next. For example, the high-pass filter may have the HPROVIDER handle value "1" during one execution, and the value "2" the next. You must, therefore, always use these functions to obtain the proper HPROVIDER handle value at runtime.

Group: Digital Filter Services
Related Sections: All-Pass Filter, Band-Pass Filter, Capture Filter, Chorus Filter, Compressor Filter, Delay Filter, Flange Filter, Gain Block Filter, High-Pass Filter, Low-Pass Filter, Parametric Equalizer Filter, Phaser Filter, Resonator Filter, Ring-Amplitude Modulator Filter, Shelving Equalizer Filter, Volume Ramp Filter
Related Functions: AIL_enumerate_filters, AIL_open_filter, AIL_set_sample_processor
Related Basic Types: HPROVIDER, S32, char *
Related FAQs: How do I set a DSP filter on a sample?


AIL_enumerate_filters

The function AIL_enumerate_filters enumerates the available filter processors for display or for opening.

S32 AIL_enumerate_filters(
  HPROENUM *next,
  HPROVIDER *dest,
  char * *name
);

Out Parameters

next
is a pointer that MSS uses to keep track of the next provider to return. You initialize the next variable with the constant HPROENUM_FIRST before the first call to AIL_enumerate_filters.
dest
points to an address that receives the HPROVIDER handle that is used for AIL_open_filter.
name
receives a pointer to the provider's text description (such as "High-pass filter"). This parameter is usually used to match the filter you're interested in.

Returns

0 if no further filters were found; non-zero if another filter was found.

Discussion

You can call this function before AIL_open_filter or AIL_set_sample_processor to find out what filters are installed on the system. If you know the specific filter than you want to use, then you probably want to use the AIL_find_filter function.

The HPROVIDER handle values returned by this function can change from one program execution to the next. For example, the high-pass filter may have the HPROVIDER handle value "1" during one execution, and the value "2" the next. You must, therefore, always use these functions to obtain the proper HPROVIDER handle value at runtime.

Output filters such as Dolby, DTS, and SRS matrix filters and the DirectSound3D/EAX voice filters have an .FLT extension, but they won't be enumerated by this function. This function is used only to obtain a list of available per-sample DSP pipeline filters.

Example files that use this function: FILTER.CPP

Group: Digital Filter Services
Related Functions: AIL_enumerate_filters, AIL_find_filter, AIL_open_filter, AIL_set_sample_processor
Related Basic Types: HPROENUM, HPROVIDER, S32, char *
Related FAQs: How do I set a DSP filter on a sample?


AIL_open_filter

The function AIL_open_filter opens a filter to prepare it for use.

HDRIVERSTATE AIL_open_filter(
  HPROVIDER lib,
  HDIGDRIVER dig
);

In Parameters

lib
specifies the filter to open.
dig
specifies the digital driver handle to use.

Returns

A handle to the now opened filter; -1 if the filter provider is already associated with the HDIGDRIVER; or NULL if the open failed.

Discussion

You aren't required to open a filter before using it, but some filters may need to allocate memory or do other CPU-intensive processing when first opened. Calling AIL_open_filter ahead of time allows you to schedule the possible CPU hit.

This function call is optional - if you call AIL_set_sample_processor on an unopened filter, then the filter will be automatically opened.

Open filters are cleaned-up automatically at driver shutdown time, so it is only necessary to explicitly close a filter if you wish to reclaim resources consumed by a filter than you no longer intend to use.

Example files that use this function: filter.cpp, multiflt.cpp

Group: Digital Filter Services
Related Functions: AIL_close_filter, AIL_enumerate_filters, AIL_find_filter, AIL_open_filter, AIL_set_sample_processor
Related Basic Types: HDIGDRIVER, HDRIVERSTATE, HPROVIDER


AIL_close_filter

The function AIL_close_filter closes a previously opened filter.

void AIL_close_filter(
  HDRIVERSTATE filter
);

In Parameters

filter
specifies the filter to close.

Discussion

Open filters are cleaned-up automatically at driver shutdown time, so it is only necessary to explicitly close a filter if you wish to reclaim resources consumed by a filter than you no longer intend to use.

Example files that use this function: filter.cpp, multiflt.cpp

Group: Digital Filter Services
Related Functions: AIL_close_filter, AIL_open_filter
Related Basic Types: HDRIVERSTATE, void


AIL_set_sample_processor

The function AIL_set_sample_processor assigns the filter or mixer stages for a specific sample.

HPROVIDER AIL_set_sample_processor(
  HSAMPLE S,
  SAMPLESTAGE pipeline_stage,
  HPROVIDER provider
);

In Parameters

S
specifies the HSAMPLE handle to use.
pipeline_stage
specifies the stage to assign the filter to. Use one of the SAMPLESTAGE constants.
provider
specifies the provider to set. Use zero to remove the current filter.

Returns

The previously installed provider value.

Discussion

This function is usually used to install a new filter processor. Once a sample-specific filter has been installed, you can read and change sample-specific properties with the AIL_sample_stage_property function.

You remove an installed filter by calling this function with zero for the provider parameter.

In most cases, you should install any DSP filters after declaring an HSAMPLE's format and before starting playback of an HSAMPLE. Installing or removing a DSP pipeline filter on a playing HSAMPLE may cause audible artifacts. To disable an existing filter's influence on a given HSAMPLE without uninstalling the filter, set the filter's "Mix' property (if available) to 0.0.

On the original Xbox, software DSP filters cannot be applied to Xbox ADPCM samples or 8-bit PCM samples.

Example files that use this function: filter.cpp, multiflt.cpp

Group: Digital Filter Services
Related Functions: AIL_enumerate_filters, AIL_find_filter, AIL_open_filter, AIL_sample_processor, AIL_sample_stage_property, AIL_set_digital_driver_processor
Related Basic Types: HPROVIDER, HSAMPLE, SAMPLESTAGE
Related FAQs: How do I set a DSP filter on a sample?


AIL_sample_processor

The function AIL_sample_processor returns the current filter or mixer stage provider for a specific sample.

HPROVIDER AIL_sample_processor(
  HSAMPLE S,
  SAMPLESTAGE pipeline_stage
);

In Parameters

S
specifies the HSAMPLE handle to query.
pipeline_stage
specifies the stage to query. Use one of the SAMPLESTAGE constants.

Returns

The currently-installed provider.

Group: Digital Filter Services
Related Functions: AIL_enumerate_sample_stage_properties, AIL_set_sample_processor
Related Basic Types: HPROVIDER, HSAMPLE, SAMPLESTAGE


AIL_digital_driver_processor

The function AIL_digital_driver_processor returns the current default filter or mixer stage provider for a specific driver.

HPROVIDER AIL_digital_driver_processor(
  HDIGDRIVER dig,
  DIGDRVSTAGE pipeline_stage
);

In Parameters

dig
specifies the HDIGDRIVER to query.
pipeline_stage
specifies the stage to query. Use one of the SAMPLESTAGE constants.

Returns

The currently-installed provider.

Group: Digital Filter Services
Related Functions: AIL_set_digital_driver_processor
Related Basic Types: DIGDRVSTAGE, HDIGDRIVER, HPROVIDER, SAMPLESTAGE


AIL_digital_output_filter

The function AIL_digital_output_filter returns the output filter (either per-voice or matrix) provider for a specific driver.

HPROVIDER AIL_digital_output_filter(
  HDIGDRIVER dig
);

In Parameters

dig
specifies the HDIGDRIVER to query.

Returns

The output filter provider, or 0 if the driver's output format does not require an output filter.

Discussion

Certain output configurations supported by AIL_open_digital_driver, including DirectSound3D, EAX, DTS, Dolby Surround, and SRS Circle Surround(r), are implemented with extension modules called output filters. Output filters can offer additional control options beyond those available from the core MSS API. Most applications will never need to work with output filter controls directly, but those that wish to do so can obtain a handle to the current voice or matrix output filter from AIL_digital_output_filter and access provider- and driver-level properties via the AIL_filter_property and AIL_output_filter_driver_property functions.

Sample-level properties may be accessed through calls to AIL_sample_stage_property with the SP_OUTPUT stage identifier. Sample-level property control is available only for hardware voice filters such as DirectSound3D and EAX, not matrix filters such as Dolby.

You can find a list of configuration-specific properties in Digital Audio Services. See the examms demo program for an example of how to enumerate and query provider-level, driver-level, and sample-level properties.

Group: Digital Filter Services
Related Functions: AIL_digital_output_filter, AIL_enumerate_output_filter_driver_properties, AIL_enumerate_output_filter_sample_properties, AIL_filter_property, AIL_open_digital_driver, AIL_output_filter_driver_property, AIL_sample_stage_property
Related Basic Types: HDIGDRIVER, HPROVIDER


SAMPLESTAGE

The basic type SAMPLESTAGE describes the stage in the sample pipeline to install the filter on.

Fundamental Values

Value | Description
SP_FILTER_0 | Specifies the first of eight filter provider stages. SP_FILTER_0 is equivalent to SP_FILTER from versions of MSS prior to MSS 7. Once set, the filter in each slot will be executed before each buffer from the HSAMPLE is copied into the mixing buffer. You will almost always use the SP_FILTER_x stages to install and communicate with the Miles sample pipeline filters.
SP_FILTER_1 | Filter pipeline stage 1.
SP_FILTER_2 | Filter pipeline stage 2.
SP_FILTER_3 | Filter pipeline stage 3.
SP_FILTER_4 | Filter pipeline stage 4.
SP_FILTER_5 | Filter pipeline stage 5.
SP_FILTER_6 | Filter pipeline stage 6.
SP_FILTER_7 | Filter pipeline stage 7.
SP_OUTPUT | Intended to be used to address sample-level properties on output filters.
SP_MERGE | Specifies the merge provider stage. The merge provider is called to mix each HSAMPLE's current address into the internal MSS mixing build buffer.

Group: Digital Filter Services
Related Functions: AIL_digital_driver_processor, AIL_enumerate_sample_stage_properties, AIL_sample_processor, AIL_sample_stage_property, AIL_set_sample_processor


AIL_set_digital_driver_processor

The function AIL_set_digital_driver_processor assigns the default filter or mixer stages for a digital driver.

HPROVIDER AIL_set_digital_driver_processor(
  HDIGDRIVER dig,
  DIGDRVSTAGE pipeline_stage,
  HPROVIDER provider
);

In Parameters

dig
specifies the digital driver handle to use.
pipeline_stage
specifies the stage to assign the provider to. It should be set to one of the DIGDRVSTAGE constants.
provider
specifies the provider to set.

Returns

The previously installed provider value.

Discussion

This function is used to install a new mixer provider or to install default filter processors.

This function is rarely used - generally you should always use AIL_set_sample_processor to install filters or replacement mixers.

Group: Digital Filter Services
Related Functions: AIL_digital_driver_processor, AIL_set_sample_processor
Related Basic Types: DIGDRVSTAGE, HDIGDRIVER, HPROVIDER


DIGDRVSTAGE

The basic type DIGDRVSTAGE describes the stage in the driver pipeline to install the filter on.

Fundamental Values

Value | Description
DP_FLUSH | Sets the provider to be called when the mixing buffer is to be cleared to silence (before the DP_MERGE stage is called on each HSAMPLE).
DP_DEFAULT_FILTER | Sets the default filter provider for this HDIGDRIVER. Once set, each call to AIL_init_sample will set the sample's first filter provider (DP_FILTER_0) to this value.
DP_DEFAULT_MERGE | Sets the merge provider for this HDIGDRIVER. The merge provider is called to mix each HSAMPLE's current address into the internal MSS mixing build buffer.
DP_COPY | Sets the provider to be called when all mixing is completed and the internal MSS mixing build buffer needs to be scaled down from 32-bits into the final output buffer.
DP_MC_COPY | Sets the provider to be called when all mixing is completed and the internal MSS mixing build buffers need to be scaled down from 32-bits into the final multi-channel output buffer.

Group: Digital Filter Services
Related Functions: AIL_digital_driver_processor, AIL_init_sample, AIL_set_digital_driver_processor


AIL_enumerate_filter_properties

The function AIL_enumerate_filter_properties enumerates a filter's provider-level properties.

S32 AIL_enumerate_filter_properties(
  HPROVIDER filter,
  HINTENUM *next,
  RIB_INTERFACE_ENTRY *dest
);

In Parameters

filter
specifies the filter whose provider-level properties should be enumerated.

Out Parameters

next
is a pointer that MSS uses to keep track of the next property to return. You initialize the next variable with the constant HINTENUM_FIRST before the first call to AIL_enumerate_filter_properties.
dest
points to an structure of type RIB_INTERFACE_ENTRY that receives the property information. The most important field in this RIB structure is "entry_name" which is a pointer to the property name (which can then be used in the AIL_filter_property function.

Returns

0 if no further filter properties were found; non-zero if another property was found.

Discussion

Provider-level properties are properties that are set globally for a particular filter module. For properties that are specific to each sample (sample-level properties), use the AIL_enumerate_sample_stage_properties function. For properties that are specific to an output filter's binding to its HDIGDRIVER, use AIL_enumerate_output_filter_driver_properties.

Example files that use this function: filter.cpp, multiflt.cpp

Group: Digital Filter Services
Related Functions: AIL_enumerate_filter_properties, AIL_enumerate_filter_sample_properties, AIL_enumerate_output_filter_driver_properties, AIL_enumerate_sample_stage_properties, AIL_filter_property
Related Basic Types: HINTENUM, HPROVIDER, S32
Related Structures: RIB_INTERFACE_ENTRY


RIB_INTERFACE_ENTRY

The structure RIB_INTERFACE_ENTRY specifies a structure that contains RIB property information.

struct RIB_INTERFACE_ENTRY
{
  char const * entry_name;
  RIB_ENTRY_TYPE type;
  UINTa token;
  RIB_DATA_SUBTYPE subtype;
};

In Members

entry_name
Name of the desired function or property.
type
Type of the entry.
token
Token which may be used to read or modify the desired property value.
subtype
Variable type of the desired function or property.

Group: Digital Filter Services
Related Functions: AIL_enumerate_filter_properties, AIL_enumerate_filter_sample_properties, AIL_enumerate_output_filter_driver_properties, AIL_enumerate_output_filter_sample_properties, AIL_enumerate_sample_stage_properties
Related Basic Types: RIB_DATA_SUBTYPE, RIB_ENTRY_TYPE, UINTa, char const *


RIB_ENTRY_TYPE

The basic type RIB_ENTRY_TYPE describes the type of the RIB entry.

Fundamental Values

Value | Description
RIB_FUNCTION | Entry is a callable function. (Debugger value: 0).
RIB_PROPERTY | Entry is a read-only or a read-write property. (Debugger value: 1).

Group: Digital Filter Services
Related Structures: RIB_INTERFACE_ENTRY


RIB_DATA_SUBTYPE

The basic type RIB_DATA_SUBTYPE describes the variable type of the RIB entry.

Fundamental Values

Value | Description
RIB_NONE | Entry has no type (usually a callable function). (Debugger value: 0).
RIB_CUSTOM | Entry is a pointer to an application-specific structure. (Debugger value: 1).
RIB_DEC | Entry is a 32-bit integer value to be reported in decimal. (Debugger value: 2).
RIB_HEX | Entry is a 32-bit integer value to be reported in hex. (Debugger value: 3).
RIB_FLOAT | Entry is a 32-bit single-precision FP value. (Debugger value: 4).
RIB_PERCENT | Entry is a 32-bit single-precision FP value to be reported as percentage. (Debugger value: 5).
RIB_BOOL | Entry is a boolean-constrained integer value to be reported as TRUE or FALSE. (Debugger value: 6).
RIB_STRING | Entry is a pointer to a null-terminated ASCII strings. (Debugger value: 7).
RIB_READONLY | Entry is a read-only property (or-ed with other flags). (Debugger value: 0x80000000).

Group: Digital Filter Services
Related Structures: RIB_INTERFACE_ENTRY


AIL_enumerate_filter_sample_properties

The function AIL_enumerate_filter_sample_properties enumerates the possible sample-level filter properties.

S32 AIL_enumerate_filter_sample_properties(
  HPROVIDER filter,
  HINTENUM *next,
  RIB_INTERFACE_ENTRY *dest
);

In Parameters

filter
specifies the filter for which to enumerate the sample-level properties.

Out Parameters

next
is a pointer that MSS uses to keep track of the next property to return. You initialize the next variable with the constant HPROENUM_FIRST before the first call to AIL_enumerate_filter_properties.
dest
points to an structure of type RIB_INTERFACE_ENTRY that receives the property information. The most important field in this RIB structure is "entry_name" which is a pointer to the property name (which can then be used in the AIL_sample_stage_property function.

Returns

0 if no further sample properties were found; non-zero if another property was found.

Discussion

Sample-level properties are properties that are set for a single sample. For properties that are global to the filter, use the AIL_enumerate_filter_properties function.

Example files that use this function: filter.cpp, multiflt.cpp

Group: Digital Filter Services
Related Functions: AIL_enumerate_filter_properties, AIL_enumerate_sample_stage_properties, AIL_sample_stage_property
Related Basic Types: HINTENUM, HPROVIDER, S32
Related Structures: RIB_INTERFACE_ENTRY


AIL_enumerate_sample_stage_properties

The function AIL_enumerate_sample_stage_properties enumerates the possible sample-level filter properties for the filter currently assigned to a given HSAMPLE processing stage.

S32 AIL_enumerate_sample_stage_properties(
  HSAMPLE S,
  SAMPLESTAGE stage,
  HINTENUM *next,
  RIB_INTERFACE_ENTRY *dest
);

In Parameters

S
specifies the HSAMPLE whose filter sample properties should be enumerated.
stage
specifies the sample stage (SP_FILTER_0 through SP_FILTER_7, or SP_OUTPUT) whose filter sample properties should be enumerated.

Out Parameters

next
is a pointer that MSS uses to keep track of the next property to return. You initialize the next variable with the constant HPROENUM_FIRST before the first call to AIL_enumerate_filter_properties.
dest
points to an structure of type RIB_INTERFACE_ENTRY that receives the property information. The most important field in this RIB structure is "entry_name" which is a pointer to the property name (which can then be used in the AIL_sample_stage_property function.

Returns

0 if no further sample properties were found; non-zero if another property was found.

Discussion

Sample-level properties are properties that are set for a single sample. For properties that are global to the filter, use the AIL_enumerate_filter_properties function.

This function is similar to AIL_enumerate_filter_sample_properties, except it works directly with an HSAMPLE/SAMPLESTAGE pair instead of requiring you to look up the HPROVIDER with AIL_sample_processor.

Group: Digital Filter Services
Related Functions: AIL_enumerate_filter_properties, AIL_enumerate_filter_sample_properties, AIL_enumerate_output_filter_driver_properties, AIL_enumerate_output_filter_sample_properties, AIL_sample_processor, AIL_sample_stage_property
Related Basic Types: HINTENUM, HSAMPLE, S32, SAMPLESTAGE
Related Structures: RIB_INTERFACE_ENTRY


AIL_filter_property

The function AIL_filter_property retrieves and/or sets the current value of the specified provider-level property.

S32 AIL_filter_property(
  HPROVIDER filter,
  char const * name,
  void *before_value,
  void const * new_value,
  void *after_value
);

In Parameters

filter
specifies the filter to query.
name
specifies the name of the property to retrieve.
new_value
is a pointer to a new value to set. If you don't want to set the property, pass in 0.

Out Parameters

before_value
is a pointer to a variable that will contain the property value before changing it. Always use this pointer to retrieve read-only properties. You can use 0 if you don't want to retrieve the prior value.
after_value
is a pointer to a variable that will contain the property value after changing it. You can use 0 if you don't want to retrieve the post-value.

Returns

Non-zero for success, 0 for failure.

Discussion

Filter-level properties are properties that are read globally from a filter. For properties that are specific to each sample (sample-level properties), use the AIL_sample_stage_property function.

This function can retrieve or set the current value of a property.

Example files that use this function: filter.cpp, multiflt.cpp

Group: Digital Filter Services
Related Functions: AIL_digital_output_filter, AIL_enumerate_filter_properties, AIL_enumerate_output_filter_driver_properties, AIL_output_filter_driver_property, AIL_sample_stage_property
Related Basic Types: HPROVIDER, S32, char const *, void, void const *


AIL_sample_stage_property

The function AIL_sample_stage_property retrieves and/or sets the current value of the specified sample-level property.

S32 AIL_sample_stage_property(
  HSAMPLE S,
  SAMPLESTAGE pipeline_stage,
  char const * name,
  void *before_value,
  void const * new_value,
  void *after_value
);

In Parameters

S
specifies the sample whose filter should be addressed.
pipeline_stage
specifies the stage to address. Use one of the SAMPLESTAGE constants.
name
specifies the name of the property to retrieve.
new_value
is a pointer to a new value to set. If you don't want to set the property, pass in 0.

Out Parameters

before_value
is a pointer to a variable that will contain the property value before changing it. Always use this pointer to retrieve read-only properties. You can use 0 if you don't want to retrieve the prior value.
after_value
is a pointer to a variable that will contain the property value after changing it. You can use 0 if you don't want to retrieve the post-value.

Returns

Non-zero for success, 0 for failure.

Discussion

Sample-level properties are properties that are read from a single sample. For properties that are global to the filter, use the AIL_filter_property function.

This function can retrieve or set the current value of a property.

Example files that use this function: filter.cpp, multiflt.cpp

Group: Digital Filter Services
Related Sections: Creative's EAX 2 Properties, Creative's EAX 3 Properties
Related Functions: AIL_digital_output_filter, AIL_enumerate_filter_sample_properties, AIL_enumerate_output_filter_driver_properties, AIL_enumerate_output_filter_sample_properties, AIL_enumerate_sample_stage_properties, AIL_filter_property, AIL_set_sample_processor
Related Basic Types: HSAMPLE, S32, SAMPLESTAGE, char const *, void, void const *
Related FAQs: How do I set a DSP filter on a sample?, What's the best way to port my older Miles application to MSS 7?


Capture Filter

Discussion

This filter will record the final mixed output of the Miles digital audio system to a wave file, as long as a per-voice output filter like DirectSound3D/EAX is not in use. This is great for recording demos or tracking down bugs. Just set the filename and then apply the filter to the digital driver to begin recording.

Name for use with AIL_find_filter: "Capture Filter"

Properties:

"Filename": Name of the output file (pointer to zero-terminated string).

"Enabled": Recording enabled/disabled state. Range: Zero to inhibit recording; nonzero to enable recording.

See MULTIFLT.CPP for an example of how to use this filter.

Group: Digital Filter Services
Related Functions: AIL_find_filter


Low-Pass Filter

Discussion

This filter is built right into the Miles mixer. See AIL_set_sample_low_pass_cut_off for details.

You can also install the low-pass filter as a normal pipeline-stage filter like any of the others, if you wish. This can be useful if you wish to add additional low-pass filtering to an occluded sample, for instance. In this case, the following properties are available:

Name for use with AIL_find_filter: "LowPass Filter"

"Lowpass Cutoff": Cutoff Frequency. Range: 20.0 Hz to Nyquist (one-half the driver's output sample rate in Hz).

"Mix": Wet/dry mix. Range: 0.0 (no effect) to 1.0 (full effect).

When a mix value of 0.0 is specified, the filter will operate on an internal "fast path" designed to consume minimal CPU resources.

Group: Digital Filter Services
Related Sections: Band-Pass Filter, High-Pass Filter, Resonator Filter
Related Functions: AIL_find_filter, AIL_set_sample_low_pass_cut_off


EAX Compatible Reverb

Discussion

This filter is built right into the Miles mixer. See AIL_set_digital_master_reverb for details.

Group: Digital Filter Services
Related Functions: AIL_set_digital_master_reverb


High-Pass Filter

Discussion

This filter only allows frequencies above the cutoff frequency to pass.

Name for use with AIL_find_filter: "HighPass Filter"

Properties:

"Highpass Cutoff": Cutoff Frequency. Range: 20.0 Hz to Nyquist (one-half the driver's output sample rate in Hz).

"Mix": Wet/dry mix. Range: 0.0 (no effect) to 1.0 (full effect).

When a mix value of 0.0 is specified, the filter will operate on an internal "fast path" designed to consume minimal CPU resources.

Group: Digital Filter Services
Related Sections: Band-Pass Filter, Low-Pass Filter, Resonator Filter
Related Functions: AIL_find_filter


Band-Pass Filter

Discussion

This filter only allows frequencies around the center frequency to pass. This effect is useful for simulating things like telephone calls.

Name for use with AIL_find_filter: "BandPass Filter"

Properties:

"Bandpass Center": Center Frequency. Range: 20.0 Hz to Nyquist (one-half the driver's output sample rate in Hz).

"Bandpass Width": Width of Bandpass. Range: 20.0 Hz to Nyquist (one-half the driver's output sample rate in Hz).

"Mix": Wet/dry mix. Range: 0.0 (no effect) to 1.0 (full effect).

When a mix value of 0.0 is specified, the filter will operate on an internal "fast path" designed to consume minimal CPU resources.

Group: Digital Filter Services
Related Sections: All-Pass Filter, High-Pass Filter, Low-Pass Filter, Resonator Filter
Related Functions: AIL_find_filter


All-Pass Filter

Discussion

This filter has a unity-gain transfer function for all frequencies. It affects only the phase of the signal. An all-pass filter is not normally used as a standalone effect, since the human ear is insensitive to absolute phase. It is intended for use in specialized or experimental applications such as reverb signal chains.

The filter is implemented as a two-pole all-pass filter, constructed by taking twice the output of a bandpass filter and subtracting it from the original signal.

Name for use with AIL_find_filter: "AllPass Filter"

Properties:

"Allpass Center": Center Frequency. Range: 20.0 Hz to Nyquist (one-half the driver's output sample rate in Hz).

"Allpass Q": Determines the width of the phase-transition region (i.e., the band of frequencies where the phase shift goes from -90 degrees to -270 degrees). Range: 0.01 to 1.0, given as a linear percentage of the Allpass Center frequency parameter.

"Mix": Wet/dry mix. Range: 0.0 (no effect) to 1.0 (full effect).

When a mix value of 0.0 is specified, the filter will operate on an internal "fast path" designed to consume minimal CPU resources.

Group: Digital Filter Services
Related Sections: Band-Pass Filter
Related Functions: AIL_find_filter


Resonator Filter

Discussion

This filter provides a resonant filter that allows frequencies around the center to pass. The advantage of this filter is that you can "slide" the center and achieve some interesting effects.

Name for use with AIL_find_filter: "Resonator EQ Filter"

Properties:

"Resonator Center": Center Frequency. Range: 20.0 Hz to Nyquist (one-half the driver's output sample rate in Hz).

"Resonator Width": Width of Frequency. Range: 20.0 Hz to Nyquist (one-half the driver's output sample rate in Hz). Hz.

"Mix": Wet/dry mix. Range: 0.0 (no effect) to 1.0 (full effect).

When a mix value of 0.0 is specified, the filter will operate on an internal "fast path" designed to consume minimal CPU resources.

Group: Digital Filter Services
Related Sections: Band-Pass Filter, High-Pass Filter, Low-Pass Filter
Related Functions: AIL_find_filter


Delay Filter

Discussion

This filter provides a simple delay effect.

Name for use with AIL_find_filter: "Delay Filter"

Properties:

"Max Delay Time": Forces immediate reallocation of internal buffers to support delay times up to the given maximum. Range: 0.01 to 10000.0 milliseconds.

"Delay TimeL": Delay time for left channel. Range: 0.01 to "Max Delay Time" milliseconds.

"Delay TimeR": Delay time for right channel. Range: 0.01 to "Max Delay Time" milliseconds.

"Delay Feedback": Feedback regeneration of signal. Range: 0.0 to 1.0.

"Delay Feedforward": Feedforward gain. Range: 0.0 to 1.0.

"Mix": Mix of delayed signal. Range: 0.0 (original - dry) to 1.0 (full delay - wet).

When a mix value of 0.0 is specified, the filter will operate on an internal "fast path" designed to consume minimal CPU resources.

By default, the "Max Delay Time" property value is set to 300 milliseconds when the filter is initially bound to a sample. This allows you to set "Delay TimeL" and "Delay TimeR" values from 10 milliseconds to 300 milliseconds. Values outside of this range will be clamped; the only way to obtain longer delays is to set a new "Max Delay Time" property value.

Because changes to "Max Delay Time" always cause internal memory buffers to be freed and reallocated, you must not change "Max Delay Time" from within a callback function. The other preferences may be changed at any time.

Per-sample memory requirements for the internal delay buffers may be determined as follows:

   (8 * "Max Delay Time" in milliseconds * driver output rate in Hz) / 1000 bytes

Group: Digital Filter Services
Related Functions: AIL_find_filter


Parametric Equalizer Filter

Discussion

This filter allows you to select a frequency range and boost or cut the signal in that range. The boost or cut amount is smoothly ramped down in either direction in a bell curve.

Name for use with AIL_find_filter: "Parametric EQ Filter"

Properties:

"ParmEQ Center": Center Frequency. Range: 20.0 Hz to Nyquist (one-half the driver's output sample rate in Hz).

"ParmEQ Q": Width in octaves of band. Range: 0.01 to 1.0.

"ParmEQ Gain": Boost / Cut amount. Range: -18.0 to 18.0 dB.

"Mix": Wet/dry mix. Range: 0.0 (no effect) to 1.0 (full effect).

When a mix value of 0.0 is specified, the filter will operate on an internal "fast path" designed to consume minimal CPU resources.

Group: Digital Filter Services
Related Sections: Shelving Equalizer Filter
Related Functions: AIL_find_filter


Shelving Equalizer Filter

Discussion

This filter is boosts or cuts the frequencies under the low frequency by the low gain and monotonically increases the gain with the frequency. It is useful for controlling the base and treble in a sample.

Name for use with AIL_find_filter: "ShelvingEQ Filter"

Properties:

"ShelvingEQ LowFreq": Low shelf frequency. Range: 20.0 Hz to Nyquist (one-half the driver's output sample rate in Hz).

"ShelvingEQ LowGain": Boost / Cut amount. Range: -18.0 to 18.0 dB.

"ShelvingEQ HighFreq": High shelf frequency. Range: 20.0 Hz to Nyquist (one-half the driver's output sample rate in Hz).

"ShelvingEQ HighGain": Boost / Cut amount. Range: -18.0 to 18.0 dB.

"Mix": Wet/dry mix. Range: 0.0 (no effect) to 1.0 (full effect).

When a mix value of 0.0 is specified, the filter will operate on an internal "fast path" designed to consume minimal CPU resources.

Group: Digital Filter Services
Related Sections: Parametric Equalizer Filter
Related Functions: AIL_find_filter


Compressor Filter

Discussion

This filter "compresses" the dynamic range of a signal by making quiet signals louder and loud signals a bit quieter.

Name for use with AIL_find_filter: "Compressor Filter"

Properties:

"Compressor Ratio": Amount of compression. Range: 1.0 to 10.0 compression ratio.

"Compressor Gain": Legacy parameter, concatenated with "Mix" (below). Range: 0.0 to 1.0

"Mix": Mix of the compressed signal. Range: 0.0 (original - dry) to 1.0 (full compress - wet).

When a mix value of 0.0 is specified, the filter will operate on an internal "fast path" designed to consume minimal CPU resources.

Group: Digital Filter Services
Related Sections: Gain Block Filter
Related Functions: AIL_find_filter


Gain Block Filter

Discussion

This filter is a general-purpose gain block with controllable linearity characteristics. It's especially useful for creating distortion or "fuzz" effects.

Briefly, the Gain Block Filter operates by allowing the signal's instantaneous amplitude at each sample point to determine how much gain or loss is applied to that point in the signal waveform. To use this filter, you'll need to specify the desired gain levels in dB for three different signal-amplitude levels: the zero-volt baseline; the positive and negative "rails"; and a midpoint level at a position (also user-specified) between the baseline and rails.

You can think of the three user-specified gain factors as creating a simple two-segment line graph that divides the waveform's possible 16-bit amplitude range into baseline-to-midpoint and midpoint-to-rail sections. All valid sample amplitudes will fall somewhere between the baseline and rail extents of this graph -- or more precisely, within one of its two sections. When the filter processes an input sample point, it first determines which of the two graph segments the point occupies. It then amplifies or attenuates that sample point by an amount obtained by interpolating the gain parameters at the two endpoints of the graph segment. In this way, the Gain Block Filter operates in a manner similar to the "Distortion" effects plugin in Sound Forge.

If the baseline, midpoint, and rail gain factors are all within 0.1 dB of each other, then the Gain Block Filter acts as a simple amplifier or attenuator. Apply different gain levels over the waveform's amplitude range, however, and things get interesting. A nonlinear gain curve introduces harmonic distortion into a waveform. The nearest equivalent in the analog world is probably a guitar effects pedal (or a poorly-designed audio amplifier.)

Note that you have the option of specifying a different gain profile for the negative and positive halves of the signal waveform. Use the "Negative Controls Enabled" boolean property to control this behavior. If you look at the filtered output on an FFT analyzer, you'll find that changes that affect only one half of the waveform tend to cause stronger even-order harmonics to appear in the signal, while distortion applied to both halves symmetrically plays up the odd harmonics.

Name for use with AIL_find_filter: "Gain Block Filter"

Properties:

"Rail Gain": Desired gain in dB at the very limits of the waveform envelope; i.e., sample values of 0 and 65536 for a signed 16-bit waveform. Range: -96.0 to 96.0 dB.

"Midpoint Level": A linear (0.0-1.0) scalar that sets the breakpoint between the baseline-midpoint and midpoint-rail segments of the gain curve. Range: 0.0 (midpoint at baseline) to 1.0 (midpoint at rails).

"Midpoint Gain": Desired gain in dB at the midpoint level. Range: -96.0 to 96.0 dB.

"Base Gain": Desired gain in dB for sample points in the middle (the quietest part, near the zero-volt baseline) of a waveform. Range: -96.0 to 96.0 dB.

"Negative Controls Enabled": This is a boolean property (integer value of 0 or 1) that defaults to 0. When this property is set to 1, three additional properties become available ("Negative Rail Gain", "Negative Midpoint Level", and "Negative Midpoint Gain".) These are identical to the corresponding properties above, except that they control the gain profile for the bottom half of the waveform. When "Negative Controls Enabled" is 0, the standard gain/level properties apply equally to both the top and bottom halves of the waveform.

"Mix": Mix of the filtered signal. Range: 0.0 (original input signal - dry) to 1.0 (full effect - wet).

When a mix value of 0.0 is specified, the filter will operate on an internal "fast path" designed to consume minimal CPU resources. Performance is also optimized in the specific case where all gains are equal, enabling the filter to operate as a general-purpose amplifier/attenuator block.

By default, all gain properties are set to 0.0 dB, and the midpoint level is 0.5 (halfway between the signal's baseline and rails). "Negative Controls Enabled" is 0 (false) by default, meaning that changes made to the "Rail Gain", "Midpoint Level", "Midpoint Gain", and "Base Gain" properties apply equally to the negative and positive halves of the waveform.

Group: Digital Filter Services
Related Sections: Compressor Filter, Volume Ramp Filter
Related Functions: AIL_find_filter


Volume Ramp Filter

Discussion

This filter allows the you to smoothly ramp up a sound signal from one volume level to another. The volume is slowly adjusted on a sample by sample basis for completely smooth ramping. To use this filter, you first set the ramp time, and then you set the ramp level. The volume ramping will begin as soon as you set the ramp level. To set the initial ramp level to ramp from, you set the ramp time to zero first. So, to smoothly ramp the volume up from 0.0 to 1.0, use something like this:

// First, set the ramp time to zero, to init the ramp level
F32 ramp_time = 0.0f;
AIL_sample_stage_property( S, SP_FILTER_0, "Ramp Time", 0, &ramp_time, 0 );
//
// we want start at level zero
F32 ramp_level = 0.0f;
AIL_sample_stage_property( S, SP_FILTER_0, "Ramp To", 0, &ramp_level, 0 );
//
//
//ok now, set the ramp time to 1000 ms (fade in over 1 second)
ramp_time = 1000.0f;
AIL_sample_stage_property( S, SP_FILTER_0, "Ramp Time", 0, &ramp_time, 0 );
//
// ramp up to 1.0 (full volume)
F32 ramp_level = 1.0f;
AIL_sample_stage_property( S, SP_FILTER_0, "Ramp To", 0, &ramp_level, 0 );

Similarly, to fade out over one second, do something like this:

// First, set the ramp time to zero, to init the ramp level
F32 ramp_time = 0.0f;
AIL_sample_stage_property( S, SP_FILTER_0, "Ramp Time", 0, &ramp_time, 0 );
//
// we want start at full volume
F32 ramp_level = 1.0f;
AIL_sample_stage_property( S, SP_FILTER_0, "Ramp To", 0, &ramp_level, 0 );
//
//
//ok now, set the ramp time to 1000 ms (fade out over 1 second)
ramp_time = 1000.0f;
AIL_sample_stage_property( S, SP_FILTER_0, "Ramp Time", 0, &ramp_time, 0 );
//
// ramp down to 0.0 (silence)
F32 ramp_level = 0.0f;
AIL_sample_stage_property( S, SP_FILTER_0, "Ramp To", 0, &ramp_level, 0 );

Note that the filter remembers the last ramp level, so you only have to set the starting ramp level if you don't already know what it is. So, if you ramp from 0.0 to 1.0, and then later want to wrap back down to 0.0, then you don't need to set the initial ramp level to 1.0 for the fade out.

Name for use with AIL_find_filter: "Volume Ramp Filter"

Properties:

"Ramp Time": Time to apply the new ramp level over. Range: 0.0 to milliseconds. So, to fade in over 1 second, use 1000.

"Ramp To": The new volume level to smoothly ramp to. Range: 0.0 (silence) to 1.0 (full volume).

properties:

"Ramp At": Returns the current level of the volume ramping. This property will change over the ramp time until it matchs the "Ramp To" value. You can poll this property to determine when a volume ramp is complete. Range: 0.0 (silence) to 1.0 (full volume).

Group: Digital Filter Services
Related Sections: Gain Block Filter
Related Functions: AIL_find_filter
Related FAQs: How do I smoothly ramp up or ramp down the volume of a sample over time?


Ring-Amplitude Modulator Filter

Discussion

This filter uses a sine wave to modulate (change) the signal. You can create "robot" type voices or underwater type effects with lots of motion with this filter.

Name for use with AIL_find_filter: "Ring Modulator Filter"

Properties:

"Ring Mod Freq": Frequency of modulation. Range: 20.0 Hz to Nyquist (one-half the driver's output sample rate in Hz).

"Ring Mod Phase Left": Phase shift in radians applied to left channel. Range: 0.0 to 2*pi

"Ring Mod Phase Right": Phase shift in radians applied to right channel. Range: 0.0 to 2*pi

"Mix": Mix of modulated signal. Range: 0.0 (original - dry) to 1.0 (full modulation - wet).

When a mix value of 0.0 is specified, the filter will operate on an internal "fast path" designed to consume minimal CPU resources.

Group: Digital Filter Services
Related Sections: Chorus Filter, Flange Filter, Phaser Filter
Related Functions: AIL_find_filter


Phaser Filter

Discussion

This filter creates a sweeping effect by modulating a narrow notch signal filter. Many different types of sounds can be achieved with this effect (such as underwater effects). A phase shifter works by applying a narrow signal filter to a sound source. This causes various amounts of canceling of frequency components in the original signal. The filter's output is mixed back in with the original source audio signal. To get the sweeping effect, a low frequency oscillator is used to slowly move the frequency center of the notch filter. Blending the altered signal back into the signal path (called "regeneration" or "feedback") intensifies the effect.

Name for use with AIL_find_filter: "Phaser Filter"

Properties:

"Phaser Feedback": Regeneration amount. Range: 0.0 to 1.0.

"Phaser Rate": Rate the LFO moves. Range: 0.01 to 4.0.

"Phaser Range": Range in octaves. Range: 0.01 to 4.0.

"Phaser BaseFreq": Base Frequency. Range: 20.0 Hz to Nyquist (one-half the driver's output sample rate in Hz).

"Mix": Mix of phased signal. Range: 0.0 (original - dry) to 1.0 (fully phased - wet).

When a mix value of 0.0 is specified, the filter will operate on an internal "fast path" designed to consume minimal CPU resources.

Group: Digital Filter Services
Related Sections: Chorus Filter, Flange Filter, Ring-Amplitude Modulator Filter
Related Functions: AIL_find_filter


Chorus Filter

Discussion

This filter is used to add a swirling property to a sound that it is applied to, thickening the sound. An audio signal that is to be processed with chorus is first delayed by a small amount. (Typical delay times are small, in the range of 5 to 40 milliseconds.) This produces a doubling effect. Each delayed signal is then sent to a low frequency oscillator. The LFO takes the delayed signal and moves its pitch up and down, changing the tuning from sharp to flat. (The oscillator moves in the range of 1-20 cycles per seconds to get the effect.) The LFO usually runs at a slow speed; 1 to 20 oscillations per second are typical. The output of the delayed and pitch-altered signal is then mixed in with the original audio. This blending completes the chorusing effect.

Name for use with AIL_find_filter: "Chorus Filter"

Properties:

"Chorus Feedback": Regeneration amount. Range: 0.09 to 0.9 %.

"Chorus Rate": Rate of delay change. Range: 0.01 to 20.0 cycles per second.

"Chorus Depth": Depth range. Range: 0.01 to 2000.0 milliseconds per second.

"Chorus Delay": Delay of chorus signal. Range: 0.0 to 1000.0 millisecond.

"Mix": Mix of chorus signal. Range: 0.0 (original - dry) to 1.0 (fully chorused - wet).

When a mix value of 0.0 is specified, the filter will operate on an internal "fast path" designed to consume minimal CPU resources.

Group: Digital Filter Services
Related Sections: Flange Filter, Phaser Filter, Ring-Amplitude Modulator Filter
Related Functions: AIL_find_filter


Flange Filter

Discussion

This filter is also used to to produce a swirling effect on a sound. The filter delays a copy of the sample data, but uses a low frequency oscillator to vary the speed of the copy's playback. (The oscillator moves in the range of 1-20 cycles per seconds to get the effect.) Feeding the processed signal back into the device to be processed again can get a more intense effect.

Name for use with AIL_find_filter: "Flange Filter"

Properties:

"Flange Feedback": Regeneration amount. Range: -0.9 to +0.9

"Flange SweepRate": Rate of delay change. Range: 0.01 to 10.0 cycles per second.

"Flange Depth": Delay of flange signal. Range: 1.0 to 1000.0 milliseconds.

"Mix": Mix of flange signal. Range: 0.0 (original - dry) to 1.0 (fully flanged - wet).

When a mix value of 0.0 is specified, the filter will operate on an internal "fast path" designed to consume minimal CPU resources.

Group: Digital Filter Services
Related Sections: Chorus Filter, Phaser Filter, Ring-Amplitude Modulator Filter
Related Functions: AIL_find_filter


CD Audio (Redbook) Services

Discussion

The CD Audio (Redbook) Services allow you to control the CD device to play digital audio stored in the Redbook format. CDs containing both data and audio as well as plain old normal audio CDs are stored in Redbook format.

Redbook services are not available on Xbox, Xbox 360 or Playstation 2.

CD Audio (Redbook) Services
AIL_redbook_open | opens a Red Book CD-audio device.
AIL_redbook_open_drive | opens a Red Book CD-audio device from a drive letter.
AIL_redbook_open_volume | opens a Red Book CD-audio device from a MacOS volume name.
AIL_redbook_close | closes the handle to the Red Book device.
AIL_redbook_eject | ejects the CD currently inserted in the CD-ROM.
AIL_redbook_retract | retracts the CD tray back into the CD-ROM.
AIL_redbook_id | returns an ID that will uniquely identify the CD currently inserted in the Red Book device.
AIL_redbook_status | returns the current status of the specified Red Book device.
MILES_REDBOOK_STATUS | specifies the redbook device status.
AIL_redbook_tracks | returns the number of audio tracks on the inserted CD.
AIL_redbook_track_info | returns the starting and ending millisecond offsets for a given track.
AIL_redbook_position | returns the current position in milliseconds of a playing Red Book device.
AIL_redbook_track | returns the currently play audio track number.
AIL_redbook_play | begins playback of an audio CD at the specified offset.
AIL_redbook_stop | stops playback of a Red Book CD-audio device.
AIL_redbook_pause | pauses the playback of a Red Book CD-audio device.
AIL_redbook_resume | resumes the playback of a Red Book CD-audio device.
AIL_redbook_set_volume_level | controls the volume level of the Red Book CD-audio device.
AIL_redbook_volume_level | retrieves the volume level of the Red Book CD-audio device.


AIL_redbook_open

The function AIL_redbook_open opens a Red Book CD-audio device.

HREDBOOK AIL_redbook_open(
  U32 which
);

In Parameters

which
specifies which CD device to open. Devices start at zero and increase for each additional CD-ROM that the system contains. You will almost always use zero.

Returns

A handle to the Red Book device, or NULL if the device couldn't be opened.

Discussion

This function just opens a channel to the device - it doesn't check to see if an audio CD is inserted. Use AIL_redbook_status to check for audio CDs.

Under DOS and MacOS 9, this function must not be invoked from an interrupt-based callback function.

Example files that use this function: Demo.C, AudioCD.C

Group: CD Audio (Redbook) Services
Related Functions: AIL_redbook_close, AIL_redbook_open_drive, AIL_redbook_open_volume, AIL_redbook_status
Related Basic Types: HREDBOOK, U32
Related FAQs: How do I loop a track off a CD?, How do I play a track off a CD?


AIL_redbook_open_drive

The function AIL_redbook_open_drive opens a Red Book CD-audio device from a drive letter.

HREDBOOK AIL_redbook_open_drive(
  char drive
);

In Parameters

drive
specifies which CD drive letter to open (A to Z).

Returns

A handle to the Red Book device, or NULL if the device couldn't be opened.

Discussion

This function just opens a channel to the device - it doesn't check to see if an audio CD is inserted. Use AIL_redbook_status to check for audio CDs.

Under DOS and MacOS 9, this function must not be invoked from an interrupt-based callback function.

This function is not available under MacOS.

Group: CD Audio (Redbook) Services
Related Functions: AIL_redbook_close, AIL_redbook_open, AIL_redbook_open_volume, AIL_redbook_status
Related Basic Types: HREDBOOK, char


AIL_redbook_open_volume

The function AIL_redbook_open_volume opens a Red Book CD-audio device from a MacOS volume name.

HREDBOOK AIL_redbook_open_volume(
  char const * volume
);

In Parameters

volume
specifies which CD volume.

Returns

A handle to the Red Book device, or NULL if the device couldn't be opened.

Discussion

This MacOS-only function just opens a channel to the device - it doesn't check to see if an audio CD is inserted. Use AIL_redbook_status to check for audio CDs.

Under MacOS, this function must not be invoked from an interrupt-based callback function.

Group: CD Audio (Redbook) Services
Related Functions: AIL_redbook_close, AIL_redbook_open, AIL_redbook_open_drive, AIL_redbook_status
Related Basic Types: HREDBOOK, char const *


AIL_redbook_close

The function AIL_redbook_close closes the handle to the Red Book device.

void AIL_redbook_close(
  HREDBOOK hand
);

In Parameters

hand
specifies which CD device to close.

Discussion

This function doesn't stop the CD from playing audio. Use AIL_redbook_stop if you want the playback to stop.

Under DOS and MacOS 9, this function must not be invoked from an interrupt-based callback function.

Example files that use this function: Demo.C, AudioCD.C

Group: CD Audio (Redbook) Services
Related Functions: AIL_redbook_open, AIL_redbook_open_drive, AIL_redbook_open_volume, AIL_redbook_stop
Related Basic Types: HREDBOOK, void


AIL_redbook_eject

The function AIL_redbook_eject ejects the CD currently inserted in the CD-ROM.

void AIL_redbook_eject(
  HREDBOOK hand
);

In Parameters

hand
specifies which CD device to eject the CD from.

Discussion

This function can eject either data or audio CDs.

Under DOS and MacOS 9, this function must not be invoked from an interrupt-based callback function.

Example files that use this function: Demo.C, AudioCD.C

Group: CD Audio (Redbook) Services
Related Functions: AIL_redbook_retract
Related Basic Types: HREDBOOK, void


AIL_redbook_retract

The function AIL_redbook_retract retracts the CD tray back into the CD-ROM.

void AIL_redbook_retract(
  HREDBOOK hand
);

In Parameters

hand
specifies which CD device to retract.

Discussion

This function can retract either data or audio CDs.

Under DOS and MacOS 9, this function must not be invoked from an interrupt-based callback function.

Example files that use this function: Demo.C, AudioCD.C

Group: CD Audio (Redbook) Services
Related Functions: AIL_redbook_eject
Related Basic Types: HREDBOOK, void


AIL_redbook_id

The function AIL_redbook_id returns an ID that will uniquely identify the CD currently inserted in the Red Book device.

U32 AIL_redbook_id(
  HREDBOOK hand
);

In Parameters

hand
specifies which CD device to query.

Returns

An MSS generated hash value for the CD.

Discussion

This function is useful when writing a CD-audio player to identify any CD that the user inserts.

This function generates the ID by hashing together all of the start and end offsets of each track, so the ID should be unique for every CD.

Under DOS and MacOS 9, this function must not be invoked from an interrupt-based callback function.

Group: CD Audio (Redbook) Services
Related Functions: AIL_redbook_track_info, AIL_redbook_tracks
Related Basic Types: HREDBOOK, U32


AIL_redbook_status

The function AIL_redbook_status returns the current status of the specified Red Book device.

U32 AIL_redbook_status(
  HREDBOOK hand
);

In Parameters

hand
specifies which CD device to query.

Returns

One of the MILES_REDBOOK_STATUS constants.

Discussion

This is the easiest way to determine if an audio CD is present.

Since an audio CD can be stopped by ejecting and or hitting a front panel button at any time, this function is usually called every couple of seconds to monitor the status of the audio system. Note that you can't call this function from a callback, so you'll have to check it in the foreground.

Under DOS and MacOS 9, this function must not be invoked from an interrupt-based callback function.

Example files that use this function: Demo.C, AudioCD.C

Group: CD Audio (Redbook) Services
Related Functions: AIL_redbook_open, AIL_redbook_open_drive, AIL_redbook_open_volume, AIL_redbook_pause, AIL_redbook_play, AIL_redbook_resume, AIL_redbook_stop
Related Basic Types: HREDBOOK, MILES_REDBOOK_STATUS, U32


MILES_REDBOOK_STATUS

The basic type MILES_REDBOOK_STATUS specifies the redbook device status.

Fundamental Values

Value | Description
REDBOOK_ERROR | No CD is inserted, or it isn't an audio CD. (Debugger value: 0).
REDBOOK_PLAYING | An audio CD is currently playing. (Debugger value: 1).
REDBOOK_PAUSED | An audio CD is inserted and it is paused. (Debugger value: 2).
REDBOOK_STOPPED | An audio CD is inserted and it isn't playing. (Debugger value: 3).

Group: CD Audio (Redbook) Services
Related Functions: AIL_redbook_status


AIL_redbook_tracks

The function AIL_redbook_tracks returns the number of audio tracks on the inserted CD.

U32 AIL_redbook_tracks(
  HREDBOOK hand
);

In Parameters

hand
specifies which CD device to query.

Returns

The number of CD tracks, or zero if no CD is inserted or a data CD is inserted.

Discussion

Under DOS and MacOS 9, this function must not be invoked from an interrupt-based callback function.

Example files that use this function: Demo.C, AudioCD.C

Group: CD Audio (Redbook) Services
Related Functions: AIL_redbook_id, AIL_redbook_track_info
Related Basic Types: HREDBOOK, U32


AIL_redbook_track_info

The function AIL_redbook_track_info returns the starting and ending millisecond offsets for a given track.

void AIL_redbook_track_info(
  HREDBOOK hand,
  U32 tracknum,
  U32 *startmsec,
  U32 *endmsec
);

In Parameters

hand
specifies which CD device to query.
tracknum
specifies the track number to get (the first track is number 1).

Out Parameters

startmsec
is a pointer to an integer that will receive the starting millisecond offset.
endmsec
is a pointer to an integer that will receive the ending millisecond offset.

Discussion

You can then use these offsets to play a specific track.

Note that the first track on the CD is number 1 - not zero!

You can pass in NULL for any parameters that you aren't interested in.

Under DOS and MacOS 9, this function must not be invoked from an interrupt-based callback function.

Example files that use this function: Demo.C, AudioCD.C

Group: CD Audio (Redbook) Services
Related Functions: AIL_redbook_id, AIL_redbook_play, AIL_redbook_tracks
Related Basic Types: HREDBOOK, U32, void
Related FAQs: How do I loop a track off a CD?, How do I play a track off a CD?


AIL_redbook_position

The function AIL_redbook_position returns the current position in milliseconds of a playing Red Book device.

U32 AIL_redbook_position(
  HREDBOOK hand
);

In Parameters

hand
specifies which CD device to query.

Returns

The current position of the Red Book device, or 0 if the CD isn't currently playing.

Discussion

You can get the currently playing track with the AIL_redbook_track function.

Under DOS and MacOS 9, this function must not be invoked from an interrupt-based callback function.

Example files that use this function: AudioCD.C

Group: CD Audio (Redbook) Services
Related Functions: AIL_redbook_play, AIL_redbook_track
Related Basic Types: HREDBOOK, U32


AIL_redbook_track

The function AIL_redbook_track returns the currently play audio track number.

U32 AIL_redbook_track(
  HREDBOOK hand
);

In Parameters

hand
specifies which CD device to query.

Returns

The currently playing audio track, or 0 if the CD isn't currently playing.

Discussion

Under DOS and MacOS 9, this function must not be invoked from an interrupt-based callback function.

Example files that use this function: AudioCD.C

Group: CD Audio (Redbook) Services
Related Functions: AIL_redbook_position
Related Basic Types: HREDBOOK, U32


AIL_redbook_play

The function AIL_redbook_play begins playback of an audio CD at the specified offset.

U32 AIL_redbook_play(
  HREDBOOK hand,
  U32 start_ms,
  U32 end_ms
);

In Parameters

hand
specifies which CD device to play.
start_ms
specifies the starting millisecond to play.
end_ms
specifies the ending millisecond to play.

Returns

The current playback status - see AIL_redbook_status for the possible return values.

Discussion

Playback will automatically end when the end offset is reached.

You will usually call the AIL_redbook_track_info function to get the start and end offsets of the track that you want to play - but that isn't required. You could, for example, play the last two seconds of track 5 and the first three seconds of track 6.

Track 1 does not usually start at a millisecond offset of zero - always use AIL_redbook_track_info to get starting offsets.

You can monitor the playback with AIL_redbook_status and AIL_redbook_position.

Under DOS and MacOS 9, this function must not be invoked from an interrupt-based callback function.

Example files that use this function: Demo.C, AudioCD.C

Group: CD Audio (Redbook) Services
Related Functions: AIL_redbook_pause, AIL_redbook_position, AIL_redbook_resume, AIL_redbook_status, AIL_redbook_stop, AIL_redbook_track_info
Related Basic Types: HREDBOOK, U32
Related FAQs: How do I loop a track off a CD?, How do I play a track off a CD?


AIL_redbook_stop

The function AIL_redbook_stop stops playback of a Red Book CD-audio device.

U32 AIL_redbook_stop(
  HREDBOOK hand
);

In Parameters

hand
specifies which CD device to stop.

Returns

The current playback status - see AIL_redbook_status for the possible return values.

Discussion

Under DOS and MacOS 9, this function must not be invoked from an interrupt-based callback function.

Example files that use this function: Demo.C, AudioCD.C

Group: CD Audio (Redbook) Services
Related Functions: AIL_redbook_close, AIL_redbook_pause, AIL_redbook_play, AIL_redbook_resume, AIL_redbook_status
Related Basic Types: HREDBOOK, U32


AIL_redbook_pause

The function AIL_redbook_pause pauses the playback of a Red Book CD-audio device.

U32 AIL_redbook_pause(
  HREDBOOK hand
);

In Parameters

hand
specifies which CD device to pause.

Returns

The current playback status - see AIL_redbook_status for the possible return values.

Discussion

Red Book CD devices don't have a hardware pause function. MSS simulates pausing by querying the current position of the playback and then stopping it. To resume playback, MSS just starts the playback at the previously saved position.

Under DOS and MacOS 9, this function must not be invoked from an interrupt-based callback function.

Example files that use this function: Demo.C, AudioCD.C

Group: CD Audio (Redbook) Services
Related Functions: AIL_redbook_play, AIL_redbook_resume, AIL_redbook_status, AIL_redbook_stop
Related Basic Types: HREDBOOK, U32


AIL_redbook_resume

The function AIL_redbook_resume resumes the playback of a Red Book CD-audio device.

U32 AIL_redbook_resume(
  HREDBOOK hand
);

In Parameters

hand
specifies which CD device to resume.

Returns

The current playback status - see AIL_redbook_status for the possible return values.

Discussion

Red Book CD devices don't have a hardware pause function. MSS simulates pausing by querying the current position of the playback and then stopping it. To resume playback, MSS just starts the playback at the previously saved position.

Under DOS and MacOS 9, this function must not be invoked from an interrupt-based callback function.

Example files that use this function: Demo.C, AudioCD.C

Group: CD Audio (Redbook) Services
Related Functions: AIL_redbook_pause, AIL_redbook_play, AIL_redbook_status, AIL_redbook_stop
Related Basic Types: HREDBOOK, U32


AIL_redbook_set_volume_level

The function AIL_redbook_set_volume_level controls the volume level of the Red Book CD-audio device.

S32 AIL_redbook_set_volume_level(
  HREDBOOK hand,
  F32 volume
);

In Parameters

hand
specifies which CD device to control.
volume
is the new volume level (0 to 1.0).

Returns

The new volume level.

Discussion

Under Windows, MSS uses the "aux" device for volume control.

Under Win32 and Win64, MSS uses the Windows mixer API.

Under MacOS, MSS uses the system volume control panel.

Under DOS, MSS adjusts the CD-ROM's hardware volume.

Under DOS and MacOS 9, this function must not be invoked from an interrupt-based callback function.

Example files that use this function: AudioCD.C

Group: CD Audio (Redbook) Services
Related Functions: AIL_redbook_volume_level
Related Basic Types: F32, HREDBOOK, S32


AIL_redbook_volume_level

The function AIL_redbook_volume_level retrieves the volume level of the Red Book CD-audio device.

F32 AIL_redbook_volume_level(
  HREDBOOK hand
);

In Parameters

hand
specifies which CD device to query.

Returns

The current volume level.

Discussion

Under Windows, MSS uses the "aux" device for volume control.

Under Win32 and Win64, MSS uses the Windows mixer API.

Under MacOS, MSS uses the system volume control panel.

Under DOS, MSS adjusts the CD-ROM's hardware volume.

Under DOS and MacOS 9, this function must not be invoked from an interrupt-based callback function.

Example files that use this function: AudioCD.C

Group: CD Audio (Redbook) Services
Related Functions: AIL_redbook_set_volume_level
Related Basic Types: F32, HREDBOOK


XMIDI Services

Discussion

The term ‘Extended MIDI,' or ‘XMIDI,' refers to the set of features added to the base Musical Instrument Digital Interface (MIDI) data specification by the drivers and utility programs included with the Miles Sound System's Version 2.00 release. The XMIDI standard brings many powerful features to the Miles Sound System which would otherwise be absent in a system conforming to the original MIDI standard.

Composers who are interested in getting started with XMIDI should pay particular attention to the descriptions of the Miles Sound Studio and MIDIECHO in the Tools-Reference Section, before moving on to the specific discussions of the Extended MIDI controllers below. It is strongly recommended that musicians with even the slightest programming knowledge (or interest) examine the XMIDI Services section as well, in order to gain the best possible understanding of the Miles Sound System's capabilities.

Programmers seeking to master effective Miles Sound System application design are also advised to familiarize themselves with the Tools-Reference section, followed by a perusal of the XMIDI Services section.

Also useful to both XMIDI composers and programmers would be a good understanding of the new DLS features found in the Miles Sound System. This information can be found in the DLS Services Section.

XMIDI Services
AIL_open_XMIDI_driver | opens an driver handle to play XMIDI data files through.
MILES_OPEN_XMIDI_FLAGS | specifies open flags for the AIL_open_XMIDI_driver function.
AIL_close_XMIDI_driver | shuts down and closes a MIDI music driver which was opened by a previous call to AIL_open_XMIDI_driver.
AIL_MIDI_handle_release | temporarily releases the hardware MIDI handle (the HMIDIOUT handle or the QuickTime MIDI handle) back to the system.
AIL_MIDI_handle_reacquire | attempts to reacquire the hardware MIDI handle (the HMIDIOUT handle or the QuickTime MIDI handle) from the system.
AIL_set_XMIDI_master_volume | establishes an overall `master volume` value which is used to scale the volumes of all subsequent XMIDI note events in all sequences.
AIL_XMIDI_master_volume | returns the current XMIDI master volume setting in use.
AIL_allocate_sequence_handle | searches for a free sequence handle and returns it to the application for use in the playback of XMIDI audio data.
AIL_release_sequence_handle | frees a sequence handle for later allocation by AIL_allocate_sequence_handle.
AIL_init_sequence | prepares a sequence handle for playback of XMIDI sequence data, and allows the application to specify the starting address and sequence number of the XMIDI sequence to be played.
AIL_start_sequence | starts playback of a sequence from its beginning.
AIL_stop_sequence | stops playback of a sequence.
AIL_resume_sequence | resumes playback of a sequence which was previously stopped.
AIL_end_sequence | terminates playback of a sequence, setting its status to SEQ_DONE<*MILES_SEQUENCE_STATUS>.
AIL_set_sequence_tempo | specifies an increase or decrease in the normal playback tempo of a sequence.
AIL_sequence_tempo | returns the current relative tempo percentage for a sequence.
AIL_set_sequence_volume | establishes a scaling factor for the value of each MIDI Part Volume Control Change (controller 7) event occurring in a sequence.
AIL_sequence_volume | returns the current sequence volume scaling value, from 0 (minimum) to 127 (maximum).
AIL_set_sequence_loop_count | arranges for a sequence to be restarted immediately upon completion, for a total of two or more iterations.
AIL_sequence_loop_count | returns the number of loop iterations remaining for the given sequence.
AIL_branch_index | moves a sequence's data pointers to the location of a specified XMIDI Sequence Branch Index controller.
AIL_sequence_position | returns the number of beats and measures elapsed since a given XMIDI sequence began playing.
AIL_set_sequence_ms_position | moves the current playback position of a sequence to the specified millisecond count.
AIL_sequence_ms_position | returns the current playback position and length of the sequence in milliseconds.
AIL_set_sequence_user_data | sets a value for one of eight user data entries associated with each sequence handle.
AIL_sequence_user_data | retrieves a value for one of eight user data entries associated with each sequence handle.
AIL_sequence_status | returns the status of a given sequence handle.
MILES_SEQUENCE_STATUS | indicates the status of an XMIDI handle.
AIL_create_wave_synthesizer | creates a `virtual wave synthesizer` by associating an XMIDI driver with a digital audio driver and a library file containing digital audio samples assigned to various MIDI patches.
AIL_destroy_wave_synthesizer | destroys a `virtual wave synthesizer` instance created by a previous call to the AIL_create_wave_synthesizer function.
AIL_MDI_driver_type | reports the MIDI synthesis technology available with a specified.
MILES_MDI_DRIVER_TYPE | describes the type of DOS MIDI driver.
AIL_set_GTL_filename_prefix | informs MSS of the prefix portion of all Global Timbre Library filenames which are associated with a particular application.
AIL_timbre_status | checks to see if a given timbre (synthesizer instrument) is loaded.
AIL_install_timbre | forces the driver to install a single timbre (synthesizer instrument), allowing it to be used for performance in a channel of an Extended MIDI (XMIDI) sequence which contains an XMIDI Patch Bank Select controller (114) with the value bank followed by a MIDI Program Change (Patch) message with the value patch.
AIL_protect_timbre | prevents the timbre bank, patch from being discarded from the synthesizer memory or local timbre cache.
AIL_unprotect_timbre | disables timbre protection for the timbre bank, patch, subjecting the timbre to the action of the normal timbre replacement algorithm.
AIL_active_sequence_count | returns the number of currently-playing sequences.
AIL_controller_value | returns any current MIDI Control Change value for any of the channels used in the specified sequence.
MILES_MIDI_VALUE | specifies a MIDI controller that can queried.
AIL_channel_notes | returns the number of notes currently turned `on` in a given MIDI channel.
AIL_register_prefix_callback | registers an application function to be called whenever an XMIDI Callback Prefix controller (108) is encountered in a playing XMIDI sequence.
AILPREFIXCB | specifies a user-defined XMIDI prefix callback.
AIL_register_trigger_callback | registers an application function to be called whenever an XMIDI Callback Trigger controller (119) is encountered in a playing XMIDI sequence.
AILTRIGGERCB | specifies a user-defined XMIDI trigger callback.
AIL_register_sequence_callback | registers an application function to be called immediately upon completion of playback of an XMIDI sequence.
AILSEQUENCECB | specifies a user-defined XMIDI end of sequence callback.
AIL_register_event_callback | registers an application function to be called immediately prior to processing each XMIDI or MIDI Channel Voice message event associated with a given driver.
AILEVENTCB | specifies a user-defined XMIDI event callback.
AIL_register_beat_callback | registers an application function to be called each time the relative beat count changes in any sequence played with the given driver.
AILBEATCB | specifies a user-defined XMIDI beat callback.
AIL_register_timbre_callback | registers an application function to be called immediately prior to installing a timbre with AIL_install_timbre or AIL_init_sequence.
AILTIMBRECB | specifies a user-defined XMIDI timbre installation callback.
AIL_register_ICA_array | allows the application to declares an array of 128 bytes whose entries may be used to replace XMIDI or MIDI controller values whose controller events are preceded by an XMIDI Indirect Controller Prefix controller (115).
AIL_lock_channel | returns an individual MIDI channel number to the application for direct MIDI message transmission, preventing any XMIDI sequence from utilizing that physical channel until its release with AIL_release_channel.
AIL_release_channel | returns a MIDI channel previously locked with AIL_lock_channel to the sequence which formerly `owned` it, if any.
AIL_map_sequence_channel | causes all events in a given sequence which are associated with a given MIDI channel seq_channel to be transmitted instead on a `remapped` MIDI channel new_channel.
AIL_true_sequence_channel | returns the physical MIDI channel number which receives MIDI and XMIDI messages transmitted on a logical channel sequence_channel by a given sequence S.
AIL_send_channel_voice_message | transmits any desired MIDI Channel Voice message on any MIDI channel.
AIL_send_sysex_message | transmits a System Exclusive message to a MIDI device driver.
AIL_midiOutOpen | assigns a Windows Multimedia Extensions low-level midiOut driver (or the MIDI Mapper device) to the Windows MSS API for MIDI music performance.
AIL_install_MDI_INI | installs and initializes the currently selected MSS .MDI driver file for XMIDI music performance under DOS.
AIL_install_MDI_driver_file | installs and initializes an MSS-compatible .MDI driver file for XMIDI music performance under DOS.


AIL_open_XMIDI_driver

The function AIL_open_XMIDI_driver opens an driver handle to play XMIDI data files through.

HMDIDRIVER AIL_open_XMIDI_driver(
  U32 flags
);

In Parameters

flags
0 or one of the MILES_OPEN_XMIDI_FLAGS constants.

Returns

If successful, this function returns a non-zero handle to an XMIDI driver. If the driver failed to open, then 0 is returned (use AIL_last_error for the cause).

Discussion

This function will open an XMIDI driver on any of the Miles platforms.

Under Win32 and Win64, MSS can use a NULL MIDI driver for the Miles software synthesizer, or it can open the hardware midiOut drivers.

Under MacOS, MSS can use a NULL MIDI driver for the Miles software synthesizer, or it can open the QuickTime software synthesize (which is somewhat limited compared to the Miles synth).

Under DOS, MSS will call AIL_install_MDI_INI to load a real-mode DOS driver.

Example files that use this function: DEMO.C

Group: XMIDI Services
Related Functions: AIL_close_XMIDI_driver, AIL_install_MDI_INI, AIL_install_MDI_driver_file, AIL_last_error, AIL_midiOutOpen, AIL_quick_handles
Related Basic Types: HMDIDRIVER, MILES_OPEN_XMIDI_FLAGS, U32
Related FAQs: How do I initialize the Miles Sound System for use?


MILES_OPEN_XMIDI_FLAGS

The basic type MILES_OPEN_XMIDI_FLAGS specifies open flags for the AIL_open_XMIDI_driver function.

Fundamental Values

Value | Description
0 | Under Windows, the default flag of zero tells Miles to open the hardware midiOut device. Under MacOS 9, the default flag opens QuickTime for MIDI output. Note that you are usually better off using the Miles software synthesizer over QuickTime (see AIL_DLS_open for details). Under DOS, the default flag simply opens the DOS driver specified in the MDI.INI file.
AIL_OPEN_XMIDI_NULL_DRIVER | This flag tells Miles to open a "NULL" MIDI driver. A null MIDI driver can only use the Miles software synthesizer for sound output - see the AIL_DLS_open function for details.

Group: XMIDI Services
Related Functions: AIL_DLS_open, AIL_open_XMIDI_driver


AIL_close_XMIDI_driver

The function AIL_close_XMIDI_driver shuts down and closes a MIDI music driver which was opened by a previous call to AIL_open_XMIDI_driver.

void AIL_close_XMIDI_driver(
  HMDIDRIVER mdi
);

In Parameters

mdi
indicates the driver to shut down and unload from memory.

Discussion

It is not necessary to call this function immediately prior to application termination, as AIL_shutdown can be used to shut down and close all loaded drivers.

Under DOS and MacOS 9, this function must not be invoked from an interrupt-based callback function.

Group: XMIDI Services
Related Functions: AIL_install_MDI_INI, AIL_install_MDI_driver_file, AIL_midiOutOpen, AIL_open_XMIDI_driver, AIL_shutdown, AIL_uninstall_driver
Related Basic Types: HMDIDRIVER, void


AIL_MIDI_handle_release

The function AIL_MIDI_handle_release temporarily releases the hardware MIDI handle (the HMIDIOUT handle or the QuickTime MIDI handle) back to the system.

S32 AIL_MIDI_handle_release(
  HMDIDRIVER mdi
);

In Parameters

mdi
indicates the driver to release to the system.

Returns

Non-zero on success. Zero if the mdi parameter is null or invalid.

Discussion

This function is usually used with the AIL_MIDI_handle_release function in the WM_ACTIVATEAPP message processing code to allow other applications to play MIDI music.

This function will automatically pause any sequences that are currently playing. These sequences will then be automatically restarted when AIL_MIDI_handle_reacquire is called.

Under MacOS 9, this function must not be invoked from an interrupt-based callback function.

This function is not supported under DOS.

Example files that use this function: DEMO.C

Group: XMIDI Services
Related Functions: AIL_MIDI_handle_reacquire, AIL_MIDI_handle_release
Related Basic Types: HMDIDRIVER, MILES_SEQUENCE_STATUS, S32


AIL_MIDI_handle_reacquire

The function AIL_MIDI_handle_reacquire attempts to reacquire the hardware MIDI handle (the HMIDIOUT handle or the QuickTime MIDI handle) from the system.

S32 AIL_MIDI_handle_reacquire(
  HMDIDRIVER mdi
);

In Parameters

mdi
indicates the driver to try to reacquire.

Returns

Non-zero on success. Zero if the MIDI handle was still in use by the system.

Discussion

This function is usually used with the AIL_MIDI_handle_release function in the WM_ACTIVATEAPP message processing code to allow other applications to play MIDI music.

This function will automatically restart any sequences that were playing when AIL_MIDI_handle_release was called.

Important!! Note that this function can fail if the digital handle is still in use, and that there is a slight delay from when a digital handle is freed to when that handle becomes available again. So, if you place this call in your WM_ACTIVATEAPP message handling code, you will have to retry the reacquire periodically if the call fails. See Demo.C for an example.

Under MacOS 9 and Win16, this function must not be invoked from an interrupt-based callback function.

This function is not supported under DOS.

Example files that use this function: DEMO.C

Group: XMIDI Services
Related Functions: AIL_MIDI_handle_release
Related Basic Types: HMDIDRIVER, S32


AIL_set_XMIDI_master_volume

The function AIL_set_XMIDI_master_volume establishes an overall "master volume" value which is used to scale the volumes of all subsequent XMIDI note events in all sequences.

void AIL_set_XMIDI_master_volume(
  HMDIDRIVER mdi,
  S32 master_volume
);

In Parameters

mdi
indicates the driver for which the new master volume setting is to be specified.
master_volume
specifies a linear volume scaling level in standard MIDI units (0-127, with 0 corresponding to complete silence and 127 corresponding to zero attenuation).

Discussion

This function controls an attenuation factor which is applied to all XMIDI note events in software. Like other MSS level-control functions, it has no effect on any hardware mixer settings.

By default, the XMIDI master volume value is initialized to 127 (no attenuation).

Group: XMIDI Services
Related Functions: AIL_XMIDI_master_volume, AIL_set_sequence_volume
Related Basic Types: HMDIDRIVER, S32, void


AIL_XMIDI_master_volume

The function AIL_XMIDI_master_volume returns the current XMIDI master volume setting in use.

S32 AIL_XMIDI_master_volume(
  HMDIDRIVER mdi
);

In Parameters

mdi
indicates the driver for which the master volume setting is to be determined.

Returns

The current XMIDI master volume setting in standard MIDI units (0-127, with 0 corresponding to complete silence and 127 corresponding to zero attenuation).

Discussion

By default, the XMIDI master volume value is initialized to 127 (no attenuation).

Group: XMIDI Services
Related Functions: AIL_sequence_volume, AIL_set_XMIDI_master_volume
Related Basic Types: HMDIDRIVER, S32


AIL_allocate_sequence_handle

The function AIL_allocate_sequence_handle searches for a free sequence handle and returns it to the application for use in the playback of XMIDI audio data.

HSEQUENCE AIL_allocate_sequence_handle(
  HMDIDRIVER mdi
);

In Parameters

mdi
specifies which XMIDI music driver is to play the sequence data associated with the sample handle.

Returns

A handle to an available sequence slot, or NULL if all sequence handles have already been allocated.

Discussion

Each XMIDI driver, when installed, is provided with a number of sequence handles. Sequence handles are reusable descriptors for application audio data at any moment in time, each instance of a playing XMIDI sequence must be associated with a sequence handle. The number of sequence handles allocated, hence the maximum number of HSEQUENCE sequence handles available from AIL_allocate_sequence_handle, is determined by the MDI_SEQUENCES preference. This value is normally 8, but can be set to any value by use of the AIL_set_preference function prior to driver installation.

After loading a digital audio driver, the application should allocate as many sequence handles as it will require, based on the maximum number of simultaneous XMIDI sequences needed. When an XMIDI sequence is to be played, the application calls AIL_sequence_status for each of its allocated sequence handles, searching for one with the status SEQ_DONE. This indicates that the system is either finished playing the last sequence assigned to the sequence handle, or that the sequence handle has been allocated but not yet used to play a sequence. Assuming an available sequence handle is found, the next step is to call AIL_init_sequence to prepare the sequence handle for use with a new XMIDI sequence, followed by calls to set the playback volume or other playback information as desired. Playback of the sequence will begin when AIL_start_sequence is called.

Upon termination of the application program, it is not necessary to return allocated sequence handles to the MSS system with AIL_release_sequence_handle calls.

Example files that use this function: XMIPLAY.C

Group: XMIDI Services
Related Functions: AIL_allocate_sequence_handle, AIL_end_sequence, AIL_init_sequence, AIL_release_sequence_handle, AIL_sequence_status, AIL_set_preference, AIL_start_sequence, AIL_stop_sequence
Related Basic Types: HMDIDRIVER, HSEQUENCE, MILES_PREFERENCES, MILES_SEQUENCE_STATUS
Related FAQs: How do I play an XMIDI or MIDI file?


AIL_release_sequence_handle

The function AIL_release_sequence_handle frees a sequence handle for later allocation by AIL_allocate_sequence_handle.

void AIL_release_sequence_handle(
  HSEQUENCE S
);

In Parameters

S
indicates the sequence handle to release.

Discussion

Many applications which follow the guidelines for sequence allocation and playback under AIL_allocate_sequence_handle and AIL_init_sequence will not need to use this function at all. This is because sequence handles, once allocated, may be reused as many times as desired. See the descriptions of the two functions mentioned above for more information.

After a sequence handle is released, no further calls to any sequence-based functions may be executed with the released handle.

MSS version 2's "delayed release" feature is not available in MSS version 3, since sequence handles no longer need to be released and reallocated in order to play new sequences.

Upon termination of the application program, it is not necessary to return allocated sequence handles to the MSS system with AIL_release_sequence_handle calls.

Group: XMIDI Services
Related Functions: AIL_allocate_sequence_handle, AIL_init_sequence, AIL_release_sequence_handle, AIL_stop_sequence
Related Basic Types: HSEQUENCE, void


AIL_init_sequence

The function AIL_init_sequence prepares a sequence handle for playback of XMIDI sequence data, and allows the application to specify the starting address and sequence number of the XMIDI sequence to be played.

S32 AIL_init_sequence(
  HSEQUENCE S,
  void const * start,
  S32 sequence_num
);

In Parameters

S
indicates the sequence handle to initialize.
start
points to the memory-resident XMIDI file image containing the sequence to be played.
sequence_num
indicates the sequence number to play.

Returns

0 if the specified sequence could not be found in the XMIDI file image, or if the XMIDI file image itself is invalid; -1 if a timbre could not be loaded but the function was otherwise successful; or a non-zero value if the function was successful and all timbres were installed.

Discussion

This function must be called before any other sequence-oriented actions (such as volume or tempo control) are possible.

The *start parameter should point to a memory-resident image of an Extended MIDI (XMIDI) sequence file as produced by the Miles Sound Studio, or by a call to AIL_MIDI_to_XMI. An XMIDI sequence file may contain one or more sequences. The sequence_num parameter should be 0 to access the first (or only) sequence in the XMIDI file image, 1 to refer to the second sequence, and so on.

Immediately prior to returning, the DOS version of AIL_init_sequence informs the driver of the bank and patch numbers of all instruments needed to play the specified sequence. The driver then attempts to load any required instruments from a Global Timbre Library file or other instrument library file. If an error occurs during timbre installation, AIL_init_sequence will return 0, and the AIL_last_error function will contain the message Driver could not install timbre bank nnn, patch nnn. If this error occurs, it is possible to manipulate and play the sequence as if the function had succeeded, but some or all of the instrument voices may be missing. AIL_init_sequence will return a value of -1 in this case.

By default, MSS 2.X-compatible Global Timbre Library files will be loaded by the driver from the current working directory at the time AIL_init_sequence or AIL_install_timbre is called. If this is undesirable, the AIL_set_redist_directory function may be used to specify a DOS directory path to be used as part of the timbre filename prefix string.

None of the sequence-based library functions, including AIL_init_sequence, will write to the data at *FORM_XMID. The same XMIDI data file image may safely be passed to other drivers (or even used more than once per driver) without being reloaded into memory.

Because it performs driver calls which may access DOS or BIOS routines, the DOS version of AIL_init_sequence must not be called from within any timer, XMIDI, or digital sound callback function. The Windows and MacOS versions of AIL_init_sequence do not perform instrument file access, so they may be called from within a callback function without restriction.

Information regarding the creation of XMIDI sequence files may be found in the Tools Reference under the Miles Sound Studio program description, while the XMIDI IFF file format itself is described in the Extended MIDI (XMIDI) Specification Section.

Example files that use this function: XMIPLAY.C

Group: XMIDI Services
Related Sections: Extended MIDI IFF (.XMI) Structure, XMIDI Patch Bank Select (114)
Related Functions: AIL_MIDI_to_XMI, AIL_allocate_sequence_handle, AIL_background, AIL_init_sequence, AIL_install_timbre, AIL_last_error, AIL_protect_timbre, AIL_register_EOB_callback, AIL_register_EOS_callback, AIL_register_SOB_callback, AIL_register_beat_callback, AIL_register_event_callback, AIL_register_prefix_callback, AIL_register_sequence_callback, AIL_register_timer, AIL_register_trigger_callback, AIL_release_sequence_handle, AIL_set_GTL_filename_prefix, AIL_set_redist_directory, AIL_set_sequence_loop_count, AIL_start_sequence, AIL_unprotect_timbre
Related Basic Types: HSEQUENCE, MILES_PREFERENCES, S32, void const *
Related FAQs: How do I play an XMIDI or MIDI file?


AIL_start_sequence

The function AIL_start_sequence starts playback of a sequence from its beginning.

void AIL_start_sequence(
  HSEQUENCE S
);

In Parameters

S
indicates the sequence to start playing.

Discussion

AIL_resume_sequence is usually used to resume playback that has been stopped with a call to AIL_stop_sequence, but it can also be used to start a sequence without the playback position being reset to the beginning of the song.

At a minimum, the sequence handle must be initialized with AIL_init_sequence prior to starting playback of a sequence.

Example files that use this function: XMIPLAY.C

Group: XMIDI Services
Related Functions: AIL_active_sequence_count, AIL_allocate_sequence_handle, AIL_end_sequence, AIL_init_sequence, AIL_register_sequence_callback, AIL_resume_sequence, AIL_sequence_position, AIL_sequence_status, AIL_stop_sequence
Related Basic Types: HSEQUENCE, void
Related FAQs: How do I play an XMIDI or MIDI file?, How do I start an audio file somewhere in the middle?


AIL_stop_sequence

The function AIL_stop_sequence stops playback of a sequence.

void AIL_stop_sequence(
  HSEQUENCE S
);

In Parameters

S
indicates the sequence to stop playing.

Discussion

If desired, sequence playback may be resumed from the current position with a call to AIL_resume_sequence.

It is not necessary to stop playback of a sequence with this function before restarting it with AIL_start_sequence, or releasing its handle with AIL_release_sequence_handle.

After stopping playback of a sequence with AIL_stop_sequence, calls to the AIL_sequence_status function will return SEQ_STOPPED, not SEQ_DONE. If the application manages its allocated sequence handles by reusing handles whose status is SEQ_DONE, as described in the remarks for the AIL_allocate_sequence_handle function, AIL_end_sequence may be more appropriate than AIL_stop_sequence. AIL_end_sequence is similar to AIL_stop_sequence, but it resets the sequence's status to SEQ_DONE instead of SEQ_STOPPED.

AIL_stop_sequence releases all channel locks and sustain pedals, and turns off any active notes in the sequence to be stopped.

AIL_stop_sequence has no effect on sequences whose status is not SEQ_PLAYING.

Example files that use this function: XMIPLAY.C

Group: XMIDI Services
Related Functions: AIL_allocate_sequence_handle, AIL_end_sequence, AIL_release_sequence_handle, AIL_resume_sequence, AIL_sequence_status, AIL_set_sequence_loop_count, AIL_set_sequence_tempo, AIL_set_sequence_volume, AIL_start_sequence, AIL_stop_sequence
Related Basic Types: HSEQUENCE, MILES_SEQUENCE_STATUS, void


AIL_resume_sequence

The function AIL_resume_sequence resumes playback of a sequence which was previously stopped.

void AIL_resume_sequence(
  HSEQUENCE S
);

In Parameters

S
indicates the sequence to resume playing.

Discussion

AIL_resume_sequence is usable only after sequence playback has been stopped with a call to AIL_stop_sequence. It has no effect on sequences whose status is not SEQ_STOPPED.

When AIL_resume_sequence is called, all MIDI and XMIDI controller values, Program Change values, and Pitch Bender values for all of the sequence's channels are restored to their values at the time AIL_stop_sequence was called. Formerly-locked channels (if any) are re-locked, and playback continues exactly as if the sequence had never been interrupted even if other sequences were played on the same MIDI channels while the original sequence was stopped.

Since all notes in a sequence are turned off when the sequence is stopped, the same notes may appear to be "missing" immediately after the track is restarted. This condition is unavoidable due to the nature of MIDI synthesizers, but will remedy itself quickly as the sequence progresses past the point of interruption.

Group: XMIDI Services
Related Functions: AIL_end_sequence, AIL_resume_sequence, AIL_sequence_status, AIL_set_sequence_tempo, AIL_set_sequence_volume, AIL_start_sequence, AIL_stop_sequence
Related Basic Types: HSEQUENCE, MILES_SEQUENCE_STATUS, void
Related FAQs: How do I start an audio file somewhere in the middle?


AIL_end_sequence

The function AIL_end_sequence terminates playback of a sequence, setting its status to SEQ_DONE.

void AIL_end_sequence(
  HSEQUENCE S
);

In Parameters

S
indicates the sequence to terminate.

Discussion

After stopping playback of a sequence with AIL_end_sequence, calls to the AIL_sequence_status function will return SEQ_DONE, not SEQ_STOPPED. If the application manages its allocated sequence handles by reusing handles whose status is SEQ_DONE, as described in the remarks for the AIL_allocate_sequence_handle function, AIL_end_sequence may be more appropriate than AIL_stop_sequence. AIL_end_sequence is similar to AIL_stop_sequence, but it resets the sequence's status to SEQ_DONE instead of SEQ_STOPPED.

Group: XMIDI Services
Related Functions: AIL_allocate_sequence_handle, AIL_end_sequence, AIL_resume_sequence, AIL_sequence_status, AIL_set_sequence_loop_count, AIL_start_sequence, AIL_stop_sequence
Related Basic Types: HSEQUENCE, MILES_SEQUENCE_STATUS, void


AIL_set_sequence_tempo

The function AIL_set_sequence_tempo specifies an increase or decrease in the normal playback tempo of a sequence.

void AIL_set_sequence_tempo(
  HSEQUENCE S,
  S32 tempo,
  S32 milliseconds
);

In Parameters

S
indicates the sequence whose tempo is to be altered.
tempo
specifies the new tempo percentage.
milliseconds
specifies a delay time over which the requested tempo change should take place.

Discussion

Tempo values are expressed as a percentage relative to the normal (unscaled) tempo values specified in a sequence's MIDI Set Tempo (type 51H) meta-events. The normal relative tempo for a sequence will be 100, or 100%.

The milliseconds parameter allows the application to specify a number of milliseconds from 0 (immediate) to 2.1 billion (slightly more than three weeks) over which the relative tempo should ramp up or down to reach the specified value. This graduation time is measured only while the sequence is actually playing; if a sequence is paused during a ramp-up or ramp-down with a call to AIL_stop_sequence, the graduation effect itself will continue, along with the rest of the sequence's performance, upon a subsequent call to AIL_resume_sequence.

Group: XMIDI Services
Related Functions: AIL_quick_set_speed, AIL_resume_sequence, AIL_sequence_tempo, AIL_stop_sequence
Related Basic Types: HSEQUENCE, S32, void


AIL_sequence_tempo

The function AIL_sequence_tempo returns the current relative tempo percentage for a sequence.

S32 AIL_sequence_tempo(
  HSEQUENCE S
);

In Parameters

S
indicates the sequence whose relative tempo value is to be returned.

Returns

The sequence's current relative tempo percentage.

Discussion

See AIL_set_sequence_tempo for more information.

Group: XMIDI Services
Related Functions: AIL_set_sequence_tempo
Related Basic Types: HSEQUENCE, S32


AIL_set_sequence_volume

The function AIL_set_sequence_volume establishes a scaling factor for the value of each MIDI Part Volume Control Change (controller 7) event occurring in a sequence.

void AIL_set_sequence_volume(
  HSEQUENCE S,
  S32 volume,
  S32 milliseconds
);

In Parameters

S
indicates the sequence whose volume controller event values are to be scaled.
volume
specifies the volume-scaling value in standard MIDI units, from 0 (minimum) to 127 (maximum, or no scaling).
milliseconds
specifies a delay time over which the requested volume-scaling change should take place.

Discussion

Volume values are expressed as a number from 0 to 127 which acts as a multiplier for the normal (unscaled) volume levels specified in a sequence's MIDI Control Change events. The default volume-scaling value is 127, indicating no change in the sequence's Part Volume controller values.

The milliseconds parameter allows the application to specify a number of milliseconds from 0 (immediate) to 2.1 billion (slightly more than three weeks) over which the relative tempo should ramp up or down to reach the specified value. This graduation time is measured only while the sequence is actually playing; if a sequence is paused during a ramp-up or ramp-down with a call to AIL_stop_sequence, the graduation effect itself will continue, along with the rest of the sequence's performance, upon a subsequent call to AIL_resume_sequence.

Two important differences affect this function's operation under MSS version 3, as compared with MSS version 2. First, the volume value is no longer given as a percentage, but in standard MIDI units from 0 to 127. It is possible to specify volume values greater than 127, but this is not ordinarily desirable since it may cause imbalances in channel volumes relative to each other. Second, the default volume-scaling value is no longer synthesizer-specific. Under MSS version 2, the volume-scaling factor was reduced to 90% with the Roland MT-32 XMIDI driver active, to reduce distortion inherent in the Roland MT-32 synthesizer circuitry. This is no longer the case under MSS version 3, since most MT-32s in the field are now third-party "clones" rather than genuine Roland MT-32 or LAPC-1 synthesizers.

Important!AIL_set_sequence_volume will not affect MIDI channels which contain no MIDI Channel Volume Control Change (7) controller events. All MSS-compatible MIDI sequences should contain Volume Control events near the beginning of each channel; otherwise, each channel will "inherit" the volume level which was established in the last sequence played on that channel.

Group: XMIDI Services
Related Functions: AIL_resume_sequence, AIL_sequence_volume, AIL_set_XMIDI_master_volume, AIL_set_sequence_volume, AIL_stop_sequence
Related Basic Types: HSEQUENCE, MILES_PREFERENCES, S32, void
Related FAQs: I can't seem to change the volume of my XMIDI sequences, what's going on?


AIL_sequence_volume

The function AIL_sequence_volume returns the current sequence volume scaling value, from 0 (minimum) to 127 (maximum).

S32 AIL_sequence_volume(
  HSEQUENCE S
);

In Parameters

S
indicates the sequence handle whose volume is to be returned.

Returns

The sequence's current volume-scaling value.

Discussion

See AIL_set_sequence_volume for more information.

Group: XMIDI Services
Related Functions: AIL_XMIDI_master_volume, AIL_set_sequence_volume
Related Basic Types: HSEQUENCE, S32


AIL_set_sequence_loop_count

The function AIL_set_sequence_loop_count arranges for a sequence to be restarted immediately upon completion, for a total of two or more iterations.

void AIL_set_sequence_loop_count(
  HSEQUENCE S,
  S32 loop_count
);

In Parameters

S
indicates the sequence to loop.
loop_count
should be set to the desired number of iterations.

Discussion

A loop_count value of 1 results in a single iteration, with no looping. This is the default loop count value, as initialized by AIL_init_sequence.

A loop_count value of 0 creates an infinite loop, which can be interrupted by calling AIL_stop_sequence, AIL_end_sequence, or by calling AIL_set_sequence_loop_count to establish a different loop count.

loop_count values of 2 or more cause the sequence to be played a total of 2 or more times. The current number of iterations remaining may be monitored with AIL_sequence_loop_count.

This function provides a convenient way to loop sequences without requiring the composer to enclose the sequence in XMIDI For/Next...Break controllers. Under MSS version 2, the only way to loop a sequence was to use these controllers or the Sequence Branch Index controller.

Group: XMIDI Services
Related Functions: AIL_end_sequence, AIL_init_sequence, AIL_register_sequence_callback, AIL_sequence_loop_count, AIL_set_sequence_loop_count, AIL_stop_sequence
Related Basic Types: HSEQUENCE, S32, void


AIL_sequence_loop_count

The function AIL_sequence_loop_count returns the number of loop iterations remaining for the given sequence.

S32 AIL_sequence_loop_count(
  HSEQUENCE S
);

In Parameters

S
indicates the sequence handle whose current loop count is to be returned.

Returns

The sequence's current loop count. A value of 0 means that the sequence is looping indefinitely, while a value of 1 means that the sequence is on its last iteration, or is not looping at all.

Discussion

See AIL_set_sequence_loop_count for more information.

Group: XMIDI Services
Related Functions: AIL_set_sequence_loop_count
Related Basic Types: HSEQUENCE, S32


AIL_branch_index

The function AIL_branch_index moves a sequence's data pointers to the location of a specified XMIDI Sequence Branch Index controller.

void AIL_branch_index(
  HSEQUENCE S,
  U32 marker
);

In Parameters

S
indicates the sequence to branch.
marker
is the XMIDI Sequence Branch Index controller value which specifies the branch target.

Discussion

You can also use the AIL_set_sequence_ms_position function to adjust a sequence's playback position.

An XMIDI Sequence Branch Index event is defined by an Extended MIDI controller of type 120 (78h). As MIDI input files are converted into XMIDI sequence files, the location of every Sequence Index event in a special IFF "private chunk" is recorded for quick reference by the AIL_branch_index function.

Up to 128 Sequence Branch Index events, with controller values from 0 to 127, may appear in each XMIDI sequence. If a given Sequence Branch Index marker_number appears in more than one track in the original MIDI file, the conversion process will terminate with an error message.

When a sequence's pointers are adjusted by this function, any active Sustain (Hold1) controllers are not released. Therefore, "stuck notes" are a possibility unless care is taken to make sure all sustain controllers are released before or after this function is called. No controller values (volume, panpot, pitch, etc.) are affected, so it is advisable to follow each Sequence Branch Index event with MIDI events which reset all relevant MIDI controllers to reasonable values for that point in the sequence.

Normally, Sequence Branch Index events should be placed on beat or measure boundaries in the MIDI sequence, and the AIL_branch_index function should be called immediately after a new beat or measure begins (as reported by AIL_sequence_position ). Synchronizing branches in this way will ensure that future calls to AIL_sequence_position return meaningful values for sequences in which branches have been taken. Another way to ensure the accuracy of beat and measure count values is to embed an XMIDI Control Change event with a controller type of 118 (76h); see AIL_sequence_position for more information.

Group: XMIDI Services
Related Sections: XMIDI For Loop Controller (116), XMIDI Sequence Branch (109), XMIDI Sequence Branch Index (120)
Related Functions: AIL_branch_index, AIL_sequence_ms_position, AIL_sequence_position, AIL_set_sequence_ms_position
Related Basic Types: HSEQUENCE, MILES_PREFERENCES, U32, void


AIL_sequence_position

The function AIL_sequence_position returns the number of beats and measures elapsed since a given XMIDI sequence began playing.

void AIL_sequence_position(
  HSEQUENCE S,
  S32 *beat,
  S32 *measure
);

In Parameters

S
indicates the sequence for which position information is desired.

Out Parameters

beat
if not NULL, should point to a long integer into which will be stored the current sequence beat count.
measure
if not NULL, should point to a long integer into which will be stored the current sequence measure count.

Returns

The current beat and measure counts are stored in the variables pointed to by the parameters *beat and *measure.

Discussion

This function is used to let the application know when a new beat or measure has begun, for indexing, layering, or animation purposes. You can use the AIL_sequence_ms_position function to track a sequence's current position in milliseconds.

To allow an application extra time to respond to the beginning of a new beat or bar, the MDI_QUANT_ADVANCE preference may be set at any time to cause beat and measure counts to be reported a given number of XMIDI intervals (typically 1/120 second) "ahead" of their current position. MDI_QUANT_ADVANCE's default preference value is 1.

The beat and measure counters are constantly updated as long as the XMIDI sequence is playing, and are reset to 0 during a call to AIL_start_sequence. Generally, applications should watch for and pay attention to changes in the beat or measure count, rather than attempting to interpret their absolute values.

Both counters are reset to 0 when an MSS-specific XMIDI Control Change event of type 118 (76h) is encountered during playback of the sequence. This event may be embedded to ensure the validity of the beat and measure counters at critical junctures in the sequence, such as track index points.

During the XMIDI conversion process, a certain amount of MIDI timing precision is necessarily lost. Very rarely, a sequence with numerous meter map changes can cause the reported beat and measure count to temporarily lose "sync" with the actual beat and measure count as reported by the time display in the MIDI sequencer used to create the sequence. Applications which require near-perfect timing precision may be able to overcome this potential problem by increasing the XMIDI quantization rate in the MDI_SERVICE_RATE preference in the runtime system before calling AIL_MIDI_to_XMI, or, if all else fails, use XMIDI Callback Trigger controllers to inform the application of critical sequence points. It may also help to advance the sequence's MIDI events in each measure so that they begin a few ticks into the first beat of their measure.

Group: XMIDI Services
Related Sections: XMIDI Clear Beat-Bar Count (118)
Related Functions: AILBEATCB, AIL_MIDI_to_XMI, AIL_branch_index, AIL_register_beat_callback, AIL_sequence_ms_position, AIL_set_sequence_ms_position, AIL_start_sequence
Related Basic Types: HSEQUENCE, MILES_PREFERENCES, S32, void


AIL_set_sequence_ms_position

The function AIL_set_sequence_ms_position moves the current playback position of a sequence to the specified millisecond count.

void AIL_set_sequence_ms_position(
  HSEQUENCE S,
  S32 milliseconds
);

In Parameters

S
indicates the sequence for which position information is desired.
milliseconds
contains the time index in milliseconds to seek to.

Discussion

This function is usually more convenient than the more complicated seeking method used by the AIL_branch_index function.

Group: XMIDI Services
Related Functions: AIL_branch_index, AIL_sequence_ms_position, AIL_sequence_position
Related Basic Types: HSEQUENCE, S32, void


AIL_sequence_ms_position

The function AIL_sequence_ms_position returns the current playback position and length of the sequence in milliseconds.

void AIL_sequence_ms_position(
  HSEQUENCE S,
  S32 *total_milliseconds,
  S32 *current_milliseconds
);

In Parameters

S
indicates the sequence for which position information is desired.

Out Parameters

total_milliseconds
if not NULL, should point to a long integer into which will be stored the total length of the sequence.
current_milliseconds
if not NULL, should point to a long integer into which will be stored the current playback position in milliseconds.

Returns

The total milliseconds and the current milliseconds values are stored in the variables pointed to by the parameters *total_milliseconds and *current_milliseconds.

Discussion

This function is usually more convenient that the beat and measure values returned by the AIL_sequence_position function.

Group: XMIDI Services
Related Functions: AIL_branch_index, AIL_sequence_position, AIL_set_sequence_ms_position
Related Basic Types: HSEQUENCE, S32, void


AIL_set_sequence_user_data

The function AIL_set_sequence_user_data sets a value for one of eight user data entries associated with each sequence handle.

void AIL_set_sequence_user_data(
  HSEQUENCE S,
  U32 index,
  SINTa value
);

In Parameters

S
indicates the sequence for which a user data entry value is to be set.
index
is a number from 0 to 7, indicating which user data entry is to be set.
value
is the 32-bit user data value to set.

Discussion

Sequence user data entries are provided to assist application programs in keeping track of its allocated sequence handles. They are especially useful for communicating with callback functions to which only sequence handles are passed, without resorting to the use of global variables.

The MSS system never alters or initializes user data values under any circumstances even when a sequence handle is freed.

Group: XMIDI Services
Related Functions: AIL_sequence_user_data
Related Basic Types: HSEQUENCE, SINTa, U32, void


AIL_sequence_user_data

The function AIL_sequence_user_data retrieves a value for one of eight user data entries associated with each sequence handle.

SINTa AIL_sequence_user_data(
  HSEQUENCE S,
  U32 index
);

In Parameters

S
indicates the sequence for which a user data entry value is to be retrieved.
index
is a number from 0 to 7, indicating which user data entry value is to be retrieved.

Returns

The value which was previously stored at user data entry index.

Discussion

Sequence user data entries are provided to assist application programs in keeping track of its allocated sequence handles. They are especially useful for communicating with callback functions to which only sequence handles are passed, without resorting to the use of global variables.

The MSS system never alters or initializes user data values under any circumstances even when a sequence handle is freed.

Group: XMIDI Services
Related Functions: AIL_set_sequence_user_data
Related Basic Types: HSEQUENCE, SINTa, U32


AIL_sequence_status

The function AIL_sequence_status returns the status of a given sequence handle.

U32 AIL_sequence_status(
  HSEQUENCE S
);

In Parameters

S
indicates the sequence handle for which the status is to be returned.

Returns

One of the MILES_SEQUENCE_STATUS constants.

Discussion

For an example of how to use AIL_sequence_status in a typical MSS application, see the AIL_allocate_sequence_handle function description.

Group: XMIDI Services
Related Functions: AIL_active_sequence_count, AIL_allocate_sequence_handle, AIL_end_sequence, AIL_resume_sequence, AIL_sequence_status, AIL_start_sequence, AIL_stop_sequence
Related Basic Types: HSEQUENCE, MILES_SEQUENCE_STATUS, U32


MILES_SEQUENCE_STATUS

The basic type MILES_SEQUENCE_STATUS indicates the status of an XMIDI handle.

Fundamental Values

Value | Description
SEQ_DONE | Sequence has finished playing, or has never been started. (Debugger value: 2).
SEQ_PLAYING | Sequence is currently playing (active). (Debugger value: 4).
SEQ_PLAYINGBUTRELEASED | (Windows and MacOS only) Sequence is currently playing (active), but the hardware MIDI handle was released by a call to AIL_MIDI_handle_release. When the MIDI handle is reacquired, the sequence will begin playing again. (Debugger value: 2).
SEQ_STOPPED | Sequence has been stopped with AIL_stop_sequence. (Debugger value: 8).
SEQ_FREE | Sequence is available for allocation by AIL_allocate_sequence_handle. (Debugger value: 16).

Group: XMIDI Services
Related Functions: AIL_MIDI_handle_release, AIL_active_sequence_count, AIL_allocate_sequence_handle, AIL_end_sequence, AIL_resume_sequence, AIL_sequence_status, AIL_stop_sequence


AIL_create_wave_synthesizer

The function AIL_create_wave_synthesizer creates a "virtual wave synthesizer" by associating an XMIDI driver with a digital audio driver and a library file containing digital audio samples assigned to various MIDI patches.

HWAVESYNTH AIL_create_wave_synthesizer(
  HDIGDRIVER dig,
  HMDIDRIVER mdi,
  void const * wave_lib,
  S32 polyphony
);

In Parameters

dig
specifies the digital audio driver to play sampled MIDI instruments or sound effects.
mdi
specifies the XMIDI music driver to trigger the playback of sampled MIDI instruments or sound effects.
wave_lib
points to a memory-resident wave library file created with the WAVELIB program.
polyphony
specifies the number of digital sample handles to reserve for use with the virtual wave synthesizer.

Returns

A handle to the newly created virtual wave synthesizer, or NULL if insufficient memory was available.

Discussion

Note that this function is now obsolete. Applications should migrate to the DLS functions as soon as possible.

The wave library file created by WAVELIB contains a collection of digital audio samples, together with information assigning each sample an XMIDI patch bank number and a MIDI Program Change or rhythm-channel key number. The entire wave library file must be resident in memory (and VMM page-locked) during playback of sequences which make use of digital audio triggers. Refer to the current version of the example wave library list file WAVEDEMO.TXT to learn about the parameters which may be associated with wave samples.

Only one wave synthesizer instance may be associated with each XMIDI or digital audio driver. Example files that use this function: MIDIECHO.C, XDIGPLAY.C

Group: XMIDI Services
Related Sections: WAVELIB - Wave Synthesizer Librarian
Related Functions: AIL_destroy_wave_synthesizer
Related Basic Types: HDIGDRIVER, HMDIDRIVER, HWAVESYNTH, MILES_PREFERENCES, S32, void const *


AIL_destroy_wave_synthesizer

The function AIL_destroy_wave_synthesizer destroys a "virtual wave synthesizer" instance created by a previous call to the AIL_create_wave_synthesizer function.

void AIL_destroy_wave_synthesizer(
  HWAVESYNTH W
);

In Parameters

W
specifies a handle to the wave synthesizer instance to destroy.

Discussion

Note that this function is now obsolete. Applications should migrate to the DLS functions as soon as possible.

Before uninstalling either the digital or the XMIDI driver associated with a virtual wave synthesizer, the wave synthesizer instance should be destroyed by calling this function.

Example files that use this function: MIDIECHO.C, XDIGPLAY.C

Group: XMIDI Services
Related Functions: AIL_create_wave_synthesizer
Related Basic Types: HWAVESYNTH, void


AIL_MDI_driver_type

The function AIL_MDI_driver_type reports the MIDI synthesis technology available with a specified.

S32 AIL_MDI_driver_type(
  HMDIDRIVER mdi
);

In Parameters

mdi
indicates the driver whose synthesis technology is to be reported.

Returns

One of the MILES_MDI_DRIVER_TYPE constants.

Discussion

MDI driver.

This function is intended to allow applications to select different versions of their MIDI sequences based on the driver in use. Although MSS applications may use the same MIDI files across all synthesis platforms if desired, the highest level of quality can always be obtained through the use of specifically "tweaked" sequences for the General MIDI and FM platforms. The values given above range from 0 to 3 respectively; one way to take advantage of this feature is to add the ASCII letter ‘A' to the returned value and use this value to access XMIDI files whose names differ by the first letter; e.g. A_DEMO.XMI, B_DEMO.XMI, C_DEMO.XMI, and D_DEMO.XMI.

Group: XMIDI Services
Related Basic Types: HMDIDRIVER, MILES_MDI_DRIVER_TYPE, S32


MILES_MDI_DRIVER_TYPE

The basic type MILES_MDI_DRIVER_TYPE describes the type of DOS MIDI driver.

Fundamental Values

Value | Description
MDIDRVRTYPE_GM | General MIDI synthesis. Typically wavetable, enhanced FM, or physical-model synthesis with at least 24 available voices. This type of driver does not require an XMIDI Global Timbre Library file.
MDIDRVRTYPE_FM_2 | 2-operator (Yamaha YM3812/OPL2-equivalent) FM synthesis. These drivers require XMIDI Global Timbre Library files with the suffix .AD. 9 FM voices are provided by this synthesis technology.
MDIDRVRTYPE_FM_4 | 4-operator (Yamaha YMF262/OPL3-equivalent) FM synthesis. This technology offers up to 18 2-operator voices or 6 4-operator voices. Global Timbre Library files with the suffix .OPL are required for use with this type of driver.
MDIDRVRTYPE_SPKR | PC or Tandy internal speaker synthesis. Drivers of this type offer exceptionally poor sound quality and limited channel and controller response. No Global Timbre Library file format is supported. Few applications should include drivers of this type (which include TANDY.MDI and PCSPKR.MDI), as little market demand remains for this level of technology.

Group: XMIDI Services
Related Functions: AIL_MDI_driver_type


AIL_set_GTL_filename_prefix

The function AIL_set_GTL_filename_prefix informs MSS of the prefix portion of all Global Timbre Library filenames which are associated with a particular application.

void AIL_set_GTL_filename_prefix(
  char const * prefix
);

In Parameters

prefix
points to a valid DOS filename prefix.

Discussion

Global Timbre Library files contain instruments for MSS 2.X-generation synthesizer drivers such as those for the Yamaha OPL2- and OPL3- based boards, and the Roland MT-32.

By default, the AIL_install_MDI_driver_file and AIL_install_MDI_driver_image functions will assume that all Global Timbre Library filenames begin with the DOS prefix "FATMAN". This prefix is combined with the driver-specific GTL suffix, such as ".AD" for the 2-operator Ad Lib OPL2-type drivers, to yield the complete filename under which the driver expects to find a GTL file containing instrument definitions for the application. This function must be called before installing the .MDI driver or drivers, to declare a different GTL filename prefix.

One use for this feature might be for programs which use custom Yamaha and/or MT-32 GTL files. For example, if you're custom patches were called "CUSTOM.AD" and "CUSTOM.OPL", then simply add a call such as AIL_set_GTL_filename_prefix("CUSTOM") before calling AIL_install_MDI_driver_file or AIL_install_MDI_driver_image.

MSS 2.X-compatible Global Timbre Library files are loaded by the driver from the current working directory at the time AIL_init_sequence or AIL_install_timbre is called. If this is undesirable, the AIL_set_redist_directory function may be used to specify a DOS directory path to be used as part of the timbre filename prefix string.

Drivers for later devices such as the Gravis UltraSound card use proprietary instrument libraries rather than GTL files. Other drivers, such as the MPU401 General MIDI driver MPU401.MDI, do not make any provisions for instrument loading at all. AIL_set_GTL_filename_prefix will have no effect when either of these driver types are installed.

The current version of the Windows and MacOS system does not support custom MIDI instruments. The default MIDI instrument set used by the selected midiOut driver will be used instead.

Group: XMIDI Services
Related Functions: AIL_init_sequence, AIL_install_MDI_driver_file, AIL_install_MDI_driver_image, AIL_install_timbre, AIL_set_GTL_filename_prefix, AIL_set_redist_directory
Related Basic Types: char const *, void


AIL_timbre_status

The function AIL_timbre_status checks to see if a given timbre (synthesizer instrument) is loaded.

S32 AIL_timbre_status(
  HMDIDRIVER mdi,
  S32 bank,
  S32 patch
);

In Parameters

mdi
indicates the driver whose supported device is to be checked.
bank
specifies the XMIDI Patch Bank Select (controller 114) value associated with the desired timbre.
patch
specifies the MIDI Program Change value associated with the desired timbre.

Returns

0 if the timbre bank, patch is not present in the synthesizer memory or local timbre cache associated with driver mdi; otherwise, a non-zero value is returned.

Discussion

General MIDI synthesizers with built-in (ROM) timbres, such as the Roland Sound Canvas, will always return a non-zero value for timbres in bank 0. This is because the 128 possible timbres in bank 0 are mapped directly to the synthesizer's built-in instrument timbres.

This function may be useful by applications which play note-based sound effects with custom timbres. It allows the application to avoid the time delay involved in accessing the Global Timbre Library file and uploading a timbre when the timbre is already present in the local timbre cache. Most application programs, however, will not need to call AIL_timbre_status.

Under DOS, this function must not be invoked from an interrupt-based callback function.

The current version of the Windows and MacOS system does not support custom MIDI instruments. The default MIDI instrument set used by the selected midiOut driver will be used instead.

Group: XMIDI Services
Related Functions: AIL_install_timbre, AIL_protect_timbre, AIL_timbre_status, AIL_unprotect_timbre
Related Basic Types: HMDIDRIVER, S32


AIL_install_timbre

The function AIL_install_timbre forces the driver to install a single timbre (synthesizer instrument), allowing it to be used for performance in a channel of an Extended MIDI (XMIDI) sequence which contains an XMIDI Patch Bank Select controller (114) with the value bank followed by a MIDI Program Change (Patch) message with the value patch.

S32 AIL_install_timbre(
  HMDIDRIVER mdi,
  S32 bank,
  S32 patch
);

In Parameters

mdi
indicates the driver for whose device the timbre is to be installed.
bank
specifies the XMIDI Patch Bank Select (controller 114) value associated with the desired timbre.
patch
specifies the MIDI Program Change value associated with the desired timbre.

Returns

0 if the specified timbre was not found in the library or could not be installed; otherwise, 1.

Discussion

This function causes the driver to search its Global Timbre Library (GTL) file or a proprietary instrument file for the desired timbre, and load it into the synthesizer's memory or a local timbre cache if it is not already installed.

By default, MSS 2.X-compatible Global Timbre Library files are loaded by the driver from the current working directory at the time AIL_init_sequence or AIL_install_timbre is called. If this is undesirable, the AIL_set_redist_directory function may be used to specify a DOS directory path to be used as part of the timbre filename prefix string.

Assuming a timbre in a given bank has been uploaded through the use of this function, subsequent MIDI Program Change messages for the specified patch will "call up" the timbre which was installed for the patch number patch and current XMIDI Patch Bank Select controller (114) bank.

Synthesizers with built-in (ROM) General MIDI instruments, such as the Roland Sound Canvas, will select their built-in timbre for the specified patch when attempting to install an external timbre in bank 0. This is because the 128 possible timbres in bank 0 are always mapped directly to the synthesizer's built-in instrument timbres, and cannot be externally installed. Bank 127 is unusable by the Roland driver for a similar reason; this bank is used only on the Ad Lib and other synthesizers to map rhythm key numbers to custom timbre "patches."

Most application programs will not need to call AIL_install_timbre.

Under DOS, this function must not be invoked from an interrupt-based callback function.

The current version of the Windows and MacOS system does not support custom MIDI instruments. The default MIDI instrument set used by the selected midiOut driver will be used instead.

Group: XMIDI Services
Related Sections: DDK Function: 503H Install Timbre Set
Related Functions: AIL_init_sequence, AIL_install_timbre, AIL_protect_timbre, AIL_set_GTL_filename_prefix, AIL_set_redist_directory, AIL_timbre_status, AIL_unprotect_timbre
Related Basic Types: HMDIDRIVER, S32


AIL_protect_timbre

The function AIL_protect_timbre prevents the timbre bank, patch from being discarded from the synthesizer memory or local timbre cache.

void AIL_protect_timbre(
  HMDIDRIVER mdi,
  S32 bank,
  S32 patch
);

In Parameters

mdi
indicates the driver for which timbre protection is to be enabled.
bank
specifies the XMIDI Patch Bank Select (controller 114) value associated with the desired timbre.
patch
specifies the MIDI Program Change value associated with the desired timbre.

Discussion

If the synthesizer memory or local timbre cache does not contain sufficient space for a timbre to be installed by AIL_init_sequence or AIL_install_timbre, one or more least-recently-used timbres (the timbres least recently used to play notes) may be discarded from the cache to make room. AIL_protect_timbre and AIL_unprotect_timbre provide a means of protecting a given timbre against deletion, and of removing such protection, respectively. (Neither function will have any immediate effect on the contents of the timbre cache.)

Timbres installed by AIL_init_sequence or AIL_install_timbre are "unprotected" by default. Timbre protection may be useful in cases where it is desirable to play little-used sound-effect or music sequences at widely varying intervals during the course of an application, while avoiding the delay associated with loading and transmitting their custom timbres. Excessive use of timbre protection may give rise to "logjams" in the timbre cache.

If both the bank and the patch parameters are equal to -1, the AIL_protect_timbre and AIL_unprotect_timbre functions will protect or unprotect all timbres in the cache.

The action of these functions is analogous to the Extended MIDI Control Change event 113 (Timbre Protect).

The current version of the Windows and MacOS system does not support custom MIDI instruments. The default MIDI instrument set used by the selected midiOut driver will be used instead.

Group: XMIDI Services
Related Sections: XMIDI Timbre Protect (113)
Related Functions: AIL_init_sequence, AIL_install_timbre, AIL_protect_timbre, AIL_timbre_status, AIL_unprotect_timbre
Related Basic Types: HMDIDRIVER, S32, void


AIL_unprotect_timbre

The function AIL_unprotect_timbre disables timbre protection for the timbre bank, patch, subjecting the timbre to the action of the normal timbre replacement algorithm.

void AIL_unprotect_timbre(
  HMDIDRIVER mdi,
  S32 bank,
  S32 patch
);

In Parameters

mdi
indicates the driver for which timbre protection is to be disabled.
bank
specifies the XMIDI Patch Bank Select (controller 114) value associated with the desired timbre.
patch
specifies the MIDI Program Change value associated with the desired timbre.

Discussion

If the synthesizer memory or local timbre cache does not contain sufficient space for a timbre to be installed by AIL_init_sequence or AIL_install_timbre, one or more least-recently-used timbres (the timbres least recently used to play notes) may be discarded from the cache to make room. AIL_protect_timbre and AIL_unprotect_timbre provide a means of protecting a given timbre against deletion, and of removing such protection, respectively. (Neither function will have any immediate effect on the contents of the timbre cache.)

Timbres installed by AIL_init_sequence or AIL_install_timbre are "unprotected" by default. Timbre protection may be useful in cases where it is desirable to play little-used sound-effect or music sequences at widely varying intervals during the course of an application, while avoiding the delay associated with loading and transmitting their custom timbres. Excessive use of timbre protection may give rise to "logjams" in the timbre cache.

If both the bank and the patch parameters are equal to -1, the AIL_protect_timbre and AIL_unprotect_timbre functions will protect or unprotect all timbres in the cache.

The action of these functions is analogous to the Extended MIDI Control Change event 113 (Timbre Protect).

The current version of the Windows and MacOS system does not support custom MIDI instruments. The default MIDI instrument set used by the selected midiOut driver will be used instead.

Group: XMIDI Services
Related Sections: XMIDI Timbre Protect (113)
Related Functions: AIL_init_sequence, AIL_install_timbre, AIL_protect_timbre, AIL_timbre_status, AIL_unprotect_timbre
Related Basic Types: HMDIDRIVER, S32, void


AIL_active_sequence_count

The function AIL_active_sequence_count returns the number of currently-playing sequences.

S32 AIL_active_sequence_count(
  HMDIDRIVER mdi
);

In Parameters

mdi
specifies the XMIDI driver whose active sequence count is to be returned to the application.

Returns

The number of allocated sequence handles whose status is SEQ_PLAYING.

Discussion

This function provides a convenient alternative to calling AIL_sequence_status from within a loop to determine if any sequences are currently playing.

Example files that use this function: XMIPLAY.C

Group: XMIDI Services
Related Functions: AIL_sequence_status, AIL_start_sequence
Related Basic Types: HMDIDRIVER, MILES_SEQUENCE_STATUS, S32


AIL_controller_value

The function AIL_controller_value returns any current MIDI Control Change value for any of the channels used in the specified sequence.

S32 AIL_controller_value(
  HSEQUENCE S,
  S32 channel,
  S32 controller_num
);

In Parameters

S
indicates the sequence from which to retrieve the specified controller's value.
channel
indicates the channel from which to retrieve the specified controller's value.
controller_num
indicates the MIDI controller number whose value is to be retrieved.

Returns

The desired controller's current value as established by the specified sequence.

Discussion

As with all XMIDI functions which require an explicit channel parameter, MIDI channel numbers are passed to and from the MSS API in 1-based format (1-16), rather than the 0-based format (0-15) used when composing MIDI Status byte values.

The you can query any of the MILES_MIDI_VALUE constants.

Group: XMIDI Services
Related Functions: AIL_channel_notes
Related Basic Types: HSEQUENCE, MILES_MIDI_VALUE, S32


MILES_MIDI_VALUE

The basic type MILES_MIDI_VALUE specifies a MIDI controller that can queried.

Fundamental Values

Value | Description
110 | XMIDI Channel Lock.
111 | XMIDI Channel Lock Protection.
112 | XMIDI Voice Protection.
114 | XMIDI Patch Bank Select.
115 | XMIDI Indirect Controller Prefix.
119 | XMIDI Callback Trigger.
1 | MIDI Modulation.
7 | MIDI Part Volume.
10 | MIDI Panpot.
11 | MIDI Expression.
64 | MIDI Sustain Pedal.
91 | General MIDI Reverb.
93 | General MIDI Chorus.

Group: XMIDI Services
Related Functions: AIL_controller_value


AIL_channel_notes

The function AIL_channel_notes returns the number of notes currently turned "on" in a given MIDI channel.

S32 AIL_channel_notes(
  HSEQUENCE S,
  S32 channel
);

In Parameters

S
indicates the sequence for which a channel-based note count is to be determined.
channel
indicates the channel number in which the number of "on" notes is to be determined.

Returns

The number of notes currently playing in the specified channel.

Discussion

As with all XMIDI functions which require an explicit channel parameter, MIDI channel numbers are passed to and from the MSS API in 1-based format (1-16), rather than the 0-based format (0-15) used when composing MIDI Status byte values.

This function is intended for use in special-purpose applications (such as editors and test programs) where an indication of channel note activity is useful. Most applications will not need to call AIL_channel_notes.

Group: XMIDI Services
Related Functions: AIL_channel_notes, AIL_controller_value
Related Basic Types: HSEQUENCE, S32


AIL_register_prefix_callback

The function AIL_register_prefix_callback registers an application function to be called whenever an XMIDI Callback Prefix controller (108) is encountered in a playing XMIDI sequence.

AILPREFIXCB AIL_register_prefix_callback(
  HSEQUENCE S,
  AILPREFIXCB callback
);

In Parameters

S
indicates the sequence with which the Callback Prefix function is to be associated.
callback
should be set to the address of an application function which is prototyped as follows:

S32 AILCALLBACK foo(HSEQUENCE sequence, S32 channel, S32 value)

where sequence and channel will indicate the sequence handle and logical channel number in which the XMIDI Callback Prefix controller appeared; and value will receive the Callback Prefix controller's value as it appeared in the XMIDI sequence. The callback function should return a value from 0 to 127, which is used instead of the value for the next MIDI or XMIDI controller event which occurs in the same sequence and MIDI channel.

Returns

The address of the previously-installed Callback Prefix function handler.

Discussion

The XMIDI Callback Prefix controller can help implement an almost infinite variety of interactive MIDI music effects. Its use is similar to the XMIDI Indirect Controller Prefix controller (115). However, instead of overriding the value of the next MIDI/XMIDI controller with an entry from the Indirect Controller Array table, the Callback Prefix controller invokes a user callback function, passing its own sequence, channel number, and controller value to the application. The callback function may take any action permitted to interrupt-based callback function handlers, including calling most XMIDI API functions. The user function's return value replaces the value of the next MIDI/XMIDI controller event occurring in its channel.

It is possible to use the value returned from the Callback Prefix function to override the values of XMIDI controllers such as Sequence Branch (109) or For...Next/Break (116/117). More conventional MIDI controllers such as Part Volume (7), Panpot (10), or Reverb (91) can also be altered interactively.

Most MSS functions can be safely invoked from within callback functions. Exceptions include driver-installation or driver-shutdown functions and any other functions which may perform DOS or BIOS calls, such as AIL_init_sequence. These exceptions are noted in the descriptions of the functions involved. If in doubt about whether a particular action may safely be performed from within a callback function, contact RAD Game Tools for assistance.

Group: XMIDI Services
Related Sections: XMIDI Callback Prefix (108)
Related Functions: AILPREFIXCB, AIL_init_sequence, AIL_register_beat_callback, AIL_register_event_callback, AIL_register_sequence_callback, AIL_register_timbre_callback, AIL_register_trigger_callback
Related Basic Types: HSEQUENCE
Related FAQs: What's the deal with callbacks - are they threads, interrupts, system timers, or what?


AILPREFIXCB

The function AILPREFIXCB specifies a user-defined XMIDI prefix callback.

S32 AILCALLBACK AILPREFIXCB(
  HSEQUENCE sequence,
  S32 channel,
  S32 value
);

In Parameters

sequence
indicates the sequence handle that generated the callback.
channel
indicates the logical channel number in which the trigger controller appeared.
value
indicates the callback prefix controller's value as it appeared in the XMIDI sequence.

Returns

This callback should return a value from 0 to 127, which is used instead of the value for the next MIDI or XMIDI controller event which occurs in the same sequence and MIDI channel.

Discussion

It is possible to use the value returned from the Callback Prefix function to override the values of XMIDI controllers such as Sequence Branch (109) or For...Next/Break (116/117). More conventional MIDI controllers such as Part Volume (7), Panpot (10), or Reverb (91) can also be altered interactively.

Group: XMIDI Services
Related Functions: AIL_register_prefix_callback
Related Basic Types: HSEQUENCE, S32


AIL_register_trigger_callback

The function AIL_register_trigger_callback registers an application function to be called whenever an XMIDI Callback Trigger controller (119) is encountered in a playing XMIDI sequence.

AILTRIGGERCB AIL_register_trigger_callback(
  HSEQUENCE S,
  AILTRIGGERCB callback
);

In Parameters

S
indicates the sequence with which the Callback Trigger function handler is to be associated.
callback
should be set to the address of an application function prototyped as an AILTRIGGERCB callback.

Returns

The address of the previously-installed Callback Trigger function handler.

Discussion

Most MSS functions can be safely invoked from within callback functions. Exceptions include driver-installation or driver-shutdown functions and any other functions which may perform DOS or BIOS calls, such as AIL_init_sequence. These exceptions are noted in the descriptions of the functions involved. If in doubt about whether a particular action may safely be performed from within a callback function, contact RAD Game Tools for assistance.

Group: XMIDI Services
Related Sections: XMIDI Callback Trigger (119)
Related Functions: AILTRIGGERCB, AIL_init_sequence, AIL_register_beat_callback, AIL_register_event_callback, AIL_register_prefix_callback, AIL_register_sequence_callback, AIL_register_timbre_callback
Related Basic Types: HSEQUENCE
Related FAQs: What's the deal with callbacks - are they threads, interrupts, system timers, or what?


AILTRIGGERCB

The function AILTRIGGERCB specifies a user-defined XMIDI trigger callback.

void AILCALLBACK AILTRIGGERCB(
  HSEQUENCE sequence,
  S32 channel,
  S32 value
);

In Parameters

sequence
indicates the sequence handle that generated the callback.
channel
indicates the logical channel number in which the trigger controller appeared.
value
indicates the callback trigger controller's value as it appeared in the XMIDI sequence.

Discussion

Unlike callback functions associated with the XMIDI Callback Prefix controller (108), the Callback Trigger callback function has no return value.

Group: XMIDI Services
Related Functions: AIL_register_trigger_callback
Related Basic Types: HSEQUENCE, S32, void


AIL_register_sequence_callback

The function AIL_register_sequence_callback registers an application function to be called immediately upon completion of playback of an XMIDI sequence.

AILSEQUENCECB AIL_register_sequence_callback(
  HSEQUENCE S,
  AILSEQUENCECB callback
);

In Parameters

S
indicates the sequence with which the end-of-sequence callback function handler is to be associated.
callback
should be set to the address of an application function prototyped as an AILSEQUENCECB callback.

Returns

The address of the previously-installed end-of-sequence function handler.

Discussion

The end-of-sequence function handler will be called after the expiration of all loop iterations executed in accordance with the AIL_set_sequence_loop_count function.

If desired, the sequence may be restarted by calling AIL_start_sequence from within an end-of-sequence callback function handler.

Most MSS functions can be safely invoked from within callback functions. Exceptions include driver-installation or driver-shutdown functions and any other functions which may perform DOS or BIOS calls, such as AIL_init_sequence. These exceptions are noted in the descriptions of the functions involved. If in doubt about whether a particular action may safely be performed from within a callback function, contact RAD Game Tools for assistance.

Group: XMIDI Services
Related Functions: AILSEQUENCECB, AIL_init_sequence, AIL_register_beat_callback, AIL_register_event_callback, AIL_register_prefix_callback, AIL_register_timbre_callback, AIL_register_trigger_callback, AIL_set_sequence_loop_count, AIL_start_sequence
Related Basic Types: HSEQUENCE
Related FAQs: What's the deal with callbacks - are they threads, interrupts, system timers, or what?


AILSEQUENCECB

The function AILSEQUENCECB specifies a user-defined XMIDI end of sequence callback.

void AILCALLBACK AILSEQUENCECB(
  HSEQUENCE sequence
);

In Parameters

sequence
indicates the sequence handle that generated the callback.

Discussion

This callback is made when a sequence has completed playback.

Group: XMIDI Services
Related Functions: AIL_register_sequence_callback
Related Basic Types: HSEQUENCE, void


AIL_register_event_callback

The function AIL_register_event_callback registers an application function to be called immediately prior to processing each XMIDI or MIDI Channel Voice message event associated with a given driver.

AILEVENTCB AIL_register_event_callback(
  HMDIDRIVER mdi,
  AILEVENTCB callback
);

In Parameters

mdi
indicates the driver whose XMIDI and MIDI events are to be trapped by the callback function.
callback
should be set to the address of an application function prototyped as an AILEVENTCB callback.

Returns

The address of the previously-installed event trap function handler.

Discussion

Most MSS functions can be safely invoked from within callback functions. Exceptions include driver-installation or driver-shutdown functions and any other functions which may perform DOS or BIOS calls, such as AIL_init_sequence. These exceptions are noted in the descriptions of the functions involved. If in doubt about whether a particular action may safely be performed from within a callback function, contact RAD Game Tools for assistance.

Notwithstanding the above, it is recommended that application programmers refrain from calling other MSS XMIDI functions from within a MIDI event trap except when absolutely necessary, and only after carefully examining AILXMIDI.C's source code to guard against potentially undesirable side-effects. For example, an explicit call to AIL_send_channel_voice_message from within a MIDI event trap callback function may result in a reentrant call to the MIDI event trap function.

This function is intended primarily for use in tool and diagnostic program development, and to provide a way for the application to implement its own MIDI/XMIDI interpreter (for example, a software-based "wavetable synthesizer" such as AILXDIG.C).

Group: XMIDI Services
Related Functions: AILEVENTCB, AIL_init_sequence, AIL_register_beat_callback, AIL_register_prefix_callback, AIL_register_sequence_callback, AIL_register_timbre_callback, AIL_register_trigger_callback, AIL_send_channel_voice_message
Related Basic Types: HMDIDRIVER
Related FAQs: What's the deal with callbacks - are they threads, interrupts, system timers, or what?


AILEVENTCB

The function AILEVENTCB specifies a user-defined XMIDI event callback.

S32 AILCALLBACK AILEVENTCB(
  HSEQUENCE sequence,
  HMDIDRIVER mdi,
  S32 status,
  S32 data_1,
  S32 data_2
);

In Parameters

sequence
indicates the sequence handle that generated the callback.
mdi
indicates the driver that generated the callback.
status
indicates the MIDI Channel Voice message status which is about to be processed.
data_1
indicates the MIDI Channel Voice message first data byte which is about to be processed.
data_2
indicates the MIDI Channel Voice message second data byte which is about to be processed.

Returns

The callback function should return 0 to enable MSS to process the event and send it on to the driver layer, or 1 to inhibit further processing of the event.

Discussion

See AIL_send_channel_voice_message for more information on Channel Voice message formats.

Group: XMIDI Services
Related Functions: AIL_register_event_callback, AIL_send_channel_voice_message
Related Basic Types: HMDIDRIVER, HSEQUENCE, S32


AIL_register_beat_callback

The function AIL_register_beat_callback registers an application function to be called each time the relative beat count changes in any sequence played with the given driver.

AILBEATCB AIL_register_beat_callback(
  HMDIDRIVER mdi,
  AILBEATCB callback
);

In Parameters

mdi
indicates the driver whose beat transitions are to result in calls to the callback function.
callback
should be set to the address of an application function prototyped as an AILBEATCB callback.

Returns

The address of the previously-installed beat callback function.

Discussion

Most MSS functions can be safely invoked from within callback functions. Exceptions include driver-installation or driver-shutdown functions and any other functions which may perform DOS or BIOS calls, such as AIL_init_sequence. These exceptions are noted in the descriptions of the functions involved. If in doubt about whether a particular action may safely be performed from within a callback function, contact RAD Game Tools for assistance.

This function may be useful in interactive MIDI applications which need to perform certain actions based on beat transitions in sequences.

The beat/measure counts reported to the callback function are analogous to those provided by AIL_sequence_position. Refer to this function before using AIL_register_beat_callback!

Group: XMIDI Services
Related Functions: AILBEATCB, AIL_init_sequence, AIL_register_beat_callback, AIL_register_event_callback, AIL_register_prefix_callback, AIL_register_sequence_callback, AIL_register_timbre_callback, AIL_register_trigger_callback, AIL_sequence_position
Related Basic Types: HMDIDRIVER
Related FAQs: What's the deal with callbacks - are they threads, interrupts, system timers, or what?


AILBEATCB

The function AILBEATCB specifies a user-defined XMIDI beat callback.

void AILCALLBACK AILBEATCB(
  HMDIDRIVER mdi,
  HSEQUENCE sequence,
  S32 beat,
  S32 measure
);

In Parameters

mdi
indicates the driver that generated the callback.
sequence
indicates the sequence handle that generated the callback.
beat
indicates the new relative beat count.
measure
indicates the new relative measure count.

Discussion

The beat/measure counts reported to the callback function are analogous to those provided by AIL_sequence_position. Refer to this function before using AIL_register_beat_callback!

Group: XMIDI Services
Related Functions: AIL_register_beat_callback, AIL_sequence_position
Related Basic Types: HMDIDRIVER, HSEQUENCE, S32, void


AIL_register_timbre_callback

The function AIL_register_timbre_callback registers an application function to be called immediately prior to installing a timbre with AIL_install_timbre or AIL_init_sequence.

AILTIMBRECB AIL_register_timbre_callback(
  HMDIDRIVER mdi,
  AILTIMBRECB callback
);

In Parameters

mdi
indicates the driver whose timbre installation operations are to be intercepted by the callback function.
callback
should be set to the address of an application function prototyped as an AILTIMBRECB callback.

Returns

The address of the previously-installed timbre intercept function handler.

Discussion

This function is intended primarily for use in tool and diagnostic program development, and to provide a way for the application to implement its own MIDI/XMIDI interpreter (for example, a software-based "wavetable synthesizer" such as AILXDIG.C).

Example files that use this function: AILXDIG.C

Group: XMIDI Services
Related Functions: AILTIMBRECB, AIL_register_beat_callback, AIL_register_event_callback, AIL_register_prefix_callback, AIL_register_sequence_callback, AIL_register_trigger_callback
Related Basic Types: HMDIDRIVER
Related FAQs: What's the deal with callbacks - are they threads, interrupts, system timers, or what?


AILTIMBRECB

The function AILTIMBRECB specifies a user-defined XMIDI timbre installation callback.

S32 AILCALLBACK AILTIMBRECB(
  HMDIDRIVER mdi,
  S32 bank,
  S32 patch
);

In Parameters

mdi
indicates the driver that generated the callback.
bank
indicates the XMIDI Patch Bank Select value for the timbre.
patch
indicates the MIDI Program Change value for the timbre.

Returns

The callback function should return 0 to enable the XMIDI driver to install the timbre, or 1 to inhibit timbre installation.

Group: XMIDI Services
Related Functions: AIL_register_timbre_callback
Related Basic Types: HMDIDRIVER, S32


AIL_register_ICA_array

The function AIL_register_ICA_array allows the application to declares an array of 128 bytes whose entries may be used to replace XMIDI or MIDI controller values whose controller events are preceded by an XMIDI Indirect Controller Prefix controller (115).

void AIL_register_ICA_array(
  HSEQUENCE S,
  U8 const * array
);

In Parameters

S
indicates the sequence with which the indirect controller array is to be associated.
array
points to an array of 128 bytes whose entries may be used to replace XMIDI or MIDI controller values whose controller events are preceded by an XMIDI Indirect Controller Prefix controller (115).

Discussion

The *array parameter should point to an array of up to 128 bytes of application memory known as the sequence's Indirect Controller Array. A non-NULL value allows the XMIDI sequence to take advantage of the XMIDI Indirect Controller Prefix control event (115). This Extended MIDI Control Change event causes the very next MIDI Control Change event in its channel to ignore its own explicitly specified value, obtaining its value instead from the Indirect Controller Array's nth byte entry, where n is the Indirect Controller Prefix controller's own value. In this manner, any performance parameter normally determined by Control Change events (e.g. volume, panpot, XMIDI looping or reverb control, etc.) may be dynamically altered by the MSS application. This technique offers an alternative to explicit MIDI messages sent via the AIL_send_channel_voice_message function. (One important difference is that changes made by the application to the Indirect Controller Array will have no effect until the sequence executes an Indirect Controller Prefix/Control Change event pair which refers to the changed array entry.) If no Indirect Controller Prefix events appear in the sequence, the indirect controller array will be unused.

Because *array is accessed at interrupt time, it must be present in page-locked memory.

Group: XMIDI Services
Related Sections: XMIDI Indirect Controller Prefix (115)
Related Functions: AIL_send_channel_voice_message
Related Basic Types: HSEQUENCE, U8, void


AIL_lock_channel

The function AIL_lock_channel returns an individual MIDI channel number to the application for direct MIDI message transmission, preventing any XMIDI sequence from utilizing that physical channel until its release with AIL_release_channel.

S32 AIL_lock_channel(
  HMDIDRIVER mdi
);

In Parameters

mdi

Returns

A physical MIDI channel number from 1 to 16, or 0 if no unlocked channels were available.

Discussion

Parameters mdi specifies the driver which is to supply the locked physical channel.

MIDI channel numbers are passed to and from the MSS API in 1-based format (1-16), rather than the 0-based format (0-15) used when composing MIDI Status byte values.

This function is useful for "one-shot" sound effects which require a MIDI channel to be temporarily set aside from the normal background playback process. When accessed from within an XMIDI sequence by use of the XMIDI Channel Lock controller (110), channel locking is invaluable in overlaying sound effect sequences over a "background" score. See the Extended MIDI Specification Section for an overview of channel locking, remapping, and multiple-sequence playback.

AIL_lock_channel attempts to return the highest MIDI channel number recognized by the driver's supported synthesizer which has the fewest actively playing notes. Channels which are already locked will not be returned. Channels which have been "protected" against locking by use of the XMIDI Channel Lock Protect controller (111), will not be returned unless all other channels are locked. If no available MIDI channels are eligible for locking under these criteria, the function returns a value of 0. Otherwise, the returned channel number may range from 1 to 16, but is normally restricted to the range 2 through 9 for compatibility with a broader range of synthesizers.

Before the channel number is returned to the application, the MIDI Sustain (Hold1) controller (64) in the channel is forced to its "off" condition, and all notes playing in the channel are silenced. No other controller values or MIDI messages are initialized! It is essential for an application (or a sequence) which has just received a locked channel to initialize all MIDI parameters, including MIDI controllers, the XMIDI Patch Bank Select controller and MIDI Program Change number, and the MIDI pitch wheel, to appropriate values.

The application should use AIL_send_channel_voice_message with a NULL HSEQUENCE parameter to send MIDI and XMIDI Channel Voice messages on the locked channel. No other API function will communicate directly with a locked channel. The locked channel should be returned to the driver with AIL_release_channel as soon as it is no longer needed by the application.

Group: XMIDI Services
Related Sections: XMIDI Channel Lock (110), XMIDI Channel Lock Protect (111)
Related Functions: AIL_lock_channel, AIL_release_channel, AIL_send_channel_voice_message
Related Basic Types: HMDIDRIVER, S32


AIL_release_channel

The function AIL_release_channel returns a MIDI channel previously locked with AIL_lock_channel to the sequence which formerly "owned" it, if any.

void AIL_release_channel(
  HMDIDRIVER mdi,
  S32 channel
);

In Parameters

mdi
specifies the driver from which the locked channel was allocated.
channel
specifies a locked physical MIDI channel number from 1 to 16.

Discussion

As with all XMIDI functions which require an explicit channel parameter, MIDI channel numbers are passed to and from the MSS API in 1-based format (1-16), rather than the 0-based format (0-15) used when composing MIDI Status byte values.

Although messages from MIDI sequences are no longer sent to a MIDI channel after it is locked by the application, the driver still tracks MIDI and XMIDI controller values for that channel as they are altered by events associated with the sequence from which the channel was "stolen." When a channel is returned to the driver by AIL_release_channel (or an XMIDI Channel Lock controller with a value below 64), the function automatically updates the channel with its current MIDI and XMIDI controller values, pitch wheel, and Program Change (Patch) values, overriding any controller values set and silencing any notes turned on by the application while the channel was locked.

Group: XMIDI Services
Related Sections: XMIDI Channel Lock (110)
Related Functions: AIL_lock_channel, AIL_release_channel
Related Basic Types: HMDIDRIVER, S32, void


AIL_map_sequence_channel

The function AIL_map_sequence_channel causes all events in a given sequence which are associated with a given MIDI channel seq_channel to be transmitted instead on a "remapped" MIDI channel new_channel.

void AIL_map_sequence_channel(
  HSEQUENCE S,
  S32 seq_channel,
  S32 new_channel
);

In Parameters

S
specifies the sequence whose channel is to be remapped.
seq_channel
specifies the sequence's original MIDI channel number which is to be remapped to new_channel.
new_channel
specifies the new physical channel through which events on seq_channel will be redirected.

Discussion

As with all XMIDI functions which require an explicit channel parameter, MIDI channel numbers are passed to and from the MSS API in 1-based format (1-16), rather than the 0-based format (0-15) used when composing MIDI Status byte values.

Normally, XMIDI Channel Lock (110) controller events are embedded at the beginning of each sound-effect sequence to automatically handle the necessary channel locking and remapping necessary to overlay the sequence. Most applications will not require the high degree of direct control over a sequence's channel assignments that is provided by this function. A less flexible but somewhat simpler way of implementing dynamic Control Change events involves the use of the XMIDI Indirect Controller Prefix controller. Refer to the Extended MIDI (XMIDI) TechnicalReference, to learn about the use of this feature.

Group: XMIDI Services
Related Functions: AIL_true_sequence_channel
Related Basic Types: HSEQUENCE, S32, void


AIL_true_sequence_channel

The function AIL_true_sequence_channel returns the physical MIDI channel number which receives MIDI and XMIDI messages transmitted on a logical channel sequence_channel by a given sequence S.

S32 AIL_true_sequence_channel(
  HSEQUENCE S,
  S32 seq_channel
);

In Parameters

S
specifies the sequence for which a true (physical) channel number is to be returned.
seq_channel
specifies the remapped sequence channel for which a true (physical) channel number is to be returned.

Returns

The physical channel to which seq_channel is mapped in the specified sequence.

Discussion

As with all XMIDI functions which require an explicit channel parameter, MIDI channel numbers are passed to and from the MSS API in 1-based format (1-16), rather than the 0-based format (0-15) used when composing MIDI Status byte values.

This function allows the application to obtain the actual MIDI channel number to which a locked sequence channel (typically a MIDI channel from 11-16) has been mapped, either through a call to AIL_map_sequence_channel or by execution of an XMIDI Channel Lock (110) controller event. The application may use the returned MIDI channel number to send MIDI Channel Voice messages to the sequence's physical, or true, channel via the AIL_send_channel_voice_message function.

Group: XMIDI Services
Related Functions: AIL_map_sequence_channel, AIL_send_channel_voice_message
Related Basic Types: HSEQUENCE, S32


AIL_send_channel_voice_message

The function AIL_send_channel_voice_message transmits any desired MIDI Channel Voice message on any MIDI channel.

void AIL_send_channel_voice_message(
  HMDIDRIVER mdi,
  HSEQUENCE S,
  S32 status,
  S32 data_1,
  S32 data_2
);

In Parameters

mdi
specifies the MIDI driver to which the MIDI Channel Voice message should be transmitted.
S
if not NULL, allows the Channel Voice message to be associated with a particular sequence's channel map and XMIDI event log.
status
is the MIDI status byte for the message to be transmitted.
data_1
is the first data byte for the message to be transmitted.
data_2
is the optional second data byte for the message to be transmitted.

Discussion

This function is often used to output "one-shot" sound effects on locked MIDI channels. See AIL_lock_channel for details.

Either the mdi or the S parameter may be set to NULL. If a driver but not a sequence is specified, the MIDI message will be sent directly to the synthesizer driver layer, with no XMIDI processing or channel remapping at all. On the other hand, when using this function to introduce new controller values "on the fly" into a playing XMIDI sequence, the sequence handle should be passed to the AIL_send_channel_voice_message rather than the driver. Access to a particular sequence handle will help MSS to track current controller values for the sequence, and will allow messages to be sent to channels which sequences have locked, without requiring any calls to AIL_true_sequence_channel.

Since the range of channel numbers recognized by different synthesizers can vary widely, it may be advisable to use this function only with physical channel numbers supplied by the AIL_lock_channel function when an explicit sequence handle is not used.

For a discussion of standard MIDI Channel Voice messages and their exact format, refer to De Furia and Scacciaferro's MIDI Programmer's Handbook, pp. 59-81, or to a similar general-purpose MIDI manual. Also refer to the MIDI Implementation Chart which accompanies each supported synthesizer.

It is import to note that the lower nibble of the status bytes consists of the MIDI channel number minus 1. This allows the full range of MIDI channels from 1 to 16 to be mapped into a single four-bit binary nibble, but may be a source of confusion since all other Miles Sound System API calls express channel numbers according to conventional 1-based MIDI notation. Unfortunately, "musician-perspective" versus "programmer-perspective" numbering conflicts are everyday occurrences in the field of MIDI programming.

data_2 should be set to 0 when transmitting Channel Voice messages which have no second data byte (such as Program Change and Channel Pressure messages).

Group: XMIDI Services
Related Sections: MIDIECHO for DOS - MIDI Data Receiver and Interpreter, MIDIECHO for MacOS - MIDI Data Receiver and Interpreter, MIDIECHO for Windows - MIDI Data Receiver and Interpreter, XMIDI Channel Mute (107)
Related Functions: AILEVENTCB, AIL_lock_channel, AIL_register_ICA_array, AIL_register_event_callback, AIL_send_channel_voice_message, AIL_send_sysex_message, AIL_true_sequence_channel
Related Basic Types: HMDIDRIVER, HSEQUENCE, S32, void


AIL_send_sysex_message

The function AIL_send_sysex_message transmits a System Exclusive message to a MIDI device driver.

void AIL_send_sysex_message(
  HMDIDRIVER mdi,
  void const * buffer
);

In Parameters

mdi
specifies the MIDI driver to which the MIDI System Exclusive message should be transmitted.
buffer
points to an area of application memory containing the System Exclusive message to be transmitted.

Discussion

The System Exclusive message to be transmitted should not exceed 256 bytes for Roland MT-32 synthesizers, or 512 bytes for any other supported synthesizer. Longer System Exclusive messages should be broken up into smaller transmissions.

Certain synthesizers such as the Roland MT-32 and LAPC-1 require substantial delays between System Exclusive messages and any MIDI traffic which follows them. The AIL_delay function should be used to implement System Exclusive delays, where appropriate.

System Exclusive message addresses, formats, and functions vary according to the synthesizer in use. System Exclusive messages sent to incompatible synthesizers will generally be ignored.

Note that the interface and implementation of AIL_send_sysex_message no longer follows the MT-32-specific format used under MSS version 2. Under MSS version 3, the System Exclusive message's format should conform to the Standard MIDI Files 1.0 specification. For convenience, the relevant part of this specification is reprinted verbatim here.

A normal complete system exclusive message is stored in a MIDI file in this way:

F0 < length > < bytes to be transmitted after F0 >

The length is stored as a variable-length quantity. It specifies the number of bytes which follow it, not including the F0 or the length itself. For instance, the transmitted message F0 43 12 00 07 F7 would be stored in a MIDI file as F0 05 43 12 00 07 F7. It is required to include the F7 at the end so that the reader of the MIDI file knows that it has read the entire message.

Another form of sysex event is provided which does not imply that an F0 should be transmitted. This may be used as an "escape" to provide for the transmission of things which would not otherwise be legal, including system real-time messages, song pointer or select, MIDI Time Code, etc. This uses the F7 code:

F7 < length > < all bytes to be transmitted >

Unfortunately, some synthesizer manufacturers specify that their system exclusive messages are to be transmitted as little packets. Each packet is only part of an entire syntactical system exclusive message, but the times they are transmitted are important. Examples of this are the bytes sent in a CZ patch dump, or the FB-01's "system exclusive mode" in which micro tonal data can be transmitted. The F0 and F7 sysex events may be used together to break up syntactically complete system exclusive messages into timed packets.

An F0 sysex event is used for the first packet in a series it is a message in which the F0 should be transmitted. An F7 sysex event is used for the remainder of the packets, which do not begin with an F0. (Of course, the F7 is not considered part of the system exclusive message).

A syntactic system exclusive message must always end with an F7, even if the real-life device didn't send one, so that you know when you've reached the end of an entire sysex message without looking ahead to the next event in the MIDI file. If it's stored in one complete F0 sysex event, the last byte must be an F7. If it is broken up into packets, the last byte of the last packet must be an F7. There also must not be any transmittable MIDI events in between the packets of a multi-packet system exclusive message. This principle is illustrated in the paragraph below.

Here is an example of a multi-packet system exclusive message: suppose the bytes F0 43 12 00 were to be sent, followed by a 200-tick delay, followed by the bytes 43 12 00 43 12 00, followed by a 100-tick delay, followed by the bytes 43 12 00 F7, this would be in the MIDI File:

F0 03 43 12 00
81 48
F7 06 43 12 00 43 12 00
64
F7 04 43 12 00 F7

When reading a MIDI file, and an F7 sysex event is encountered without a preceding F0 sysex event to start a multi-packet system exclusive message sequence, it should be presumed that the F7 event is being used as an "escape". In this case, it is not necessary that it end with an F7, unless it is desired that the F7 be transmitted.

Group: XMIDI Services
Related Sections: DDK Function: 502H Transmit MIDI Data
Related Functions: AIL_delay, AIL_send_channel_voice_message, AIL_send_sysex_message
Related Basic Types: HMDIDRIVER, MILES_PREFERENCES, void, void const *


AIL_midiOutOpen

The function AIL_midiOutOpen assigns a Windows Multimedia Extensions low-level midiOut driver (or the MIDI Mapper device) to the Windows MSS API for MIDI music performance.

S32 AIL_midiOutOpen(
  HMDIDRIVER *drvr,
  LPHMIDIOUT *lphMidiOut,
  S32 dwDeviceID
);

In Parameters

dwDeviceID
identifies the midiOut driver to open. Typically, dwDeviceID should be set to the constant MIDI_MAPPER (defined in MMSYSTEM.H) to specify the MIDI Mapper device. You can also use the constant MIDI_NULL_DRIVER to load a "no-hardware" MIDI driver - this is commonly used when playing back DLS-only MIDI files.

Out Parameters

drvr
points to a variable of type HMDIDRIVER, which is typedefed as a pointer to a structure of type MDI_DRIVER. If AIL_midiOutOpen succeeds, an MDI_DRIVER structure will be allocated and initialized, and its address stored in the handle pointed to by *drvr. This address, referred to as a "driver handle" of type HMDIDRIVER, should be passed to other MSS functions which require that a driver be specified.
lphMidiOut
if not NULL, points to a variable of type HMIDIOUT which can be used by the application to communicate directly with the opened midiOut driver, if desired. Most applications do not need to communicate directly with waveOut drivers, so *lphMidiOut should normally be set to NULL.

Returns

Zero if the function was successful. Otherwise, a nonzero error code is returned. In the latter case, the AIL_last_error function may be called to obtain a text description of the error.

Discussion

For compatibility with other Miles platforms, you should use the AIL_open_XMIDI_driver function instead of this Windows-only function.

The only reason to use this function instead of AIL_open_XMIDI_driver is if you need to specifically open a particular midiOut device (by setting the dwDeviceID parameter).

If you wish to use this function, you should first become thoroughly familiar with the low-level MME functions midiOutGetNumDevs, midiOutGetDevCaps, and midiOutOpen. These functions permit the identification, selection, and initialization of the desired midiOut drivers. AIL_midiOutOpen takes the place of midiOutOpen and from the application's point of view, the parameters it requires are virtually identical to the MME function it replaces.

Group: XMIDI Services
Related Functions: AIL_close_XMIDI_driver, AIL_last_error, AIL_midiOutOpen, AIL_open_XMIDI_driver
Related Basic Types: HMDIDRIVER, LPHMIDIOUT, S32


AIL_install_MDI_INI

The function AIL_install_MDI_INI installs and initializes the currently selected MSS .MDI driver file for XMIDI music performance under DOS.

S32 AIL_install_MDI_INI(
  HMDIDRIVER *mdi
);

Out Parameters

mdi
points to an application variable of type HMDIDRIVER. If successful, AIL_install_MDI_INI will validate the application's HMDIDRIVER variable for use in subsequent function calls involving the driver. Otherwise, if an error occurs, *mdi's value will be undefined.

Returns

Returns one of the MILES_INSTALL_STATUS constants.

Discussion

For compatibility with other Miles platforms, you should use the AIL_open_XMIDI_driver function instead of this DOS-only function.

The SETSOUND Audio Configuration Utility program is provided as an extensible, device-independent installation and configuration program for MSS drivers. SETSOUND presents a list of all MSS drivers in the current working directory to the end user, allowing any desired driver to be selected and configured for use with an MSS application. The MSS example programs use AIL_install_MDI_INI and AIL_install_DIG_INI to load and initialize XMIDI and digital audio drivers in a single, easy step, eliminating the need to specify driver names on the DOS command line and ensuring compatibility with all end-user I/O configurations.

RAD Game Tools strongly recommends use of the SETSOUND utility to create DIG.INI and MDI.INI files describing the user's driver choices and configurations. MSS applications may then use the AIL_install_DIG_INI and AIL_install_MDI_INI functions instead of calling AIL_install_DIG_driver_file or AIL_install_MDI_driver_file directly.

You can use the NULL MIDI driver ("NULL.MDI") to load a "no-hardware" MIDI driver - this is commonly used when playing back DLS-only MIDI files.

This function calls AIL_read_INI to load the current MDI.INI file, and passes the parameters from the MDI.INI file to AIL_install_MDI_driver_file. Refer to the descriptions of these functions for a detailed summary of AIL_install_MDI_INI 's operation.

A return value of AIL_NO_INI_FILE generally arises from failure to run SETSOUND prior to launching the application. It does not indicate failure to detect sound hardware or problems related to driver initialization. These conditions are indicated by a return value of AIL_INIT_FAILURE.

You can use the AIL_set_redist_directory function to specify an alternate path to load the .MDI driver from (if the load fails from the current directory).

Group: XMIDI Services
Related Sections: SETSOUND - MSS Sound Configuration Utility
Related Functions: AIL_close_XMIDI_driver, AIL_install_DIG_INI, AIL_install_DIG_driver_file, AIL_install_MDI_INI, AIL_install_MDI_driver_file, AIL_open_XMIDI_driver, AIL_read_INI, AIL_set_redist_directory
Related Basic Types: HMDIDRIVER, MILES_INSTALL_STATUS, S32


AIL_install_MDI_driver_file

The function AIL_install_MDI_driver_file installs and initializes an MSS-compatible .MDI driver file for XMIDI music performance under DOS.

HMDIDRIVER AIL_install_MDI_driver_file(
  char const * filename,
  IO_PARMS * const *IO
);

In Parameters

filename
specifies the filename, including path, of the driver to install.
IO
specifies a particular I/O configuration to use when initializing the driver. If *IO is NULL or if the device cannot be detected using the specified parameters, the function will attempt to auto-detect the supported device using DOS environment strings or other driver-specific techniques.

Returns

A pointer to a dynamically allocated structure of type MDI_DRIVER, which may be passed by the application to subsequent function calls involving the driver; or NULL if an error occurs.

Discussion

For compatibility with other Miles platforms, you should use the AIL_open_XMIDI_driver function instead of this DOS-only function.

Do not embed the .MDI files in any type of proprietary library file. You can leave them on your CD-ROM, if you use the AIL_set_redist_directory function to specify their location.

RAD Game Tools strongly recommends use of the SETSOUND utility to create .INI files describing the user's driver choices and configurations. MSS applications may then use the AIL_install_DIG_INI and AIL_install_MDI_INI functions instead of calling AIL_install_DIG_driver_file or AIL_install_MDI_driver_file directly.

You can use the AIL_set_redist_directory function to specify an alternate path to load the .MDI driver from (if the load fails from the current directory).

This function must not be invoked from an interrupt-based callback function.

Group: XMIDI Services
Related Functions: AIL_close_XMIDI_driver, AIL_get_IO_environment, AIL_install_DIG_INI, AIL_install_DIG_driver_file, AIL_install_MDI_INI, AIL_install_MDI_driver_file, AIL_install_MDI_driver_image, AIL_open_XMIDI_driver, AIL_set_GTL_filename_prefix, AIL_set_redist_directory
Related Basic Types: HMDIDRIVER, char const *
Related Structures: IO_PARMS


DLS Services

Discussion

The Miles Sound System DLS Extensions package delivers full support for the MIDI Manufacturers Association's Downloadable Sounds (DLS) Level 1 specification. Available for Win32, Win64, MacOS and DOS, the DLS Extensions package consists of a simple application program interface (API) provided by either a statically- or dynamically-linked library.

The Downloadable Sounds Level 1 Architecture enables the author to define an instrument by combining a sample waveform with articulation information - a description of how to modulate the volume and pitch of the wave data in response to input from the General MIDI control set. A file containing DLS 1 instruments may be played directly in software with the MSS DLS Extensions package, or downloaded to any hardware device that supports the standard, and subsequently invoked from within a MIDI file without any special effort on the composer's part. In this way, the DLS standard delivers a common playback experience across a wide range of synthesizer platforms, eliminating concerns about inconsistencies between General MIDI instrument sets while simultaneously easing the creative restrictions imposed by the default General MIDI instrument palette.

Authoring Guidelines

To create DLS files, you will, of course, need a DLS editor. Several companies (the usual suspects, you might say) are working on DLS editors, but the only editor available at this writing (March 1, 1998) is SynthAuthor, which is available from the M.M.A. for $40.00.

The Miles Sound System's DLS support is designed for use with the existing MSS MIDI subsystem. All XMIDI functions, controllers, and features are available when DLS is in use. DLS patches are invoked in the normal way, with MIDI Program Change messages; however, it is recommended that the General MIDI bank-select controllers (0 and 32) be used instead of XMIDI Patch Bank Select (114) for all future work. In the MSS software DLS synthesizer, XMIDI Patch Bank Select emulates the GM bank controllers correctly, but this emulation is not supported by hardware-based synthesizer platforms.

Hardware/Software Interoperability

Under 32-bit Windows, the internal MSS software synthesizer API is upwardly-compatible with the API supported by the S3 86C617 Sonic Vibes(TM); chipset. Consequently, it is possible to design your application to choose between hardware- and software-based DLS providers at runtime.

This is why the Miles DLS services allow you to specify a DLS provider DLL filename in the AIL_DLS_open function - right now, you can use NULL for the software synthesizer, "S3BASE.DLL" for hardware support on Sonic Vibes sound cards, and "VORT_DLS.DLL" for hardware support on Aureal Vortex chipsets. Future versions of the Miles Sound System will be delivered with support via similar DLLs for additional platforms, such as Microsoft DirectMusic's hardware abstraction layer, so it is strongly recommended that Win32 and Win64 applications provide for dynamic selection of DLS provider DLLs.

Software Performance and Preferences

The Miles software synthesizer has many options to control the amount of CPU it extracts. Not only can you control the quality at which the digital sound from the synthesizer is created (rate, bits, and channels), but you can also adjust filtering and reverb parameters with the DLS preferences described in the Preferences section.

DLS Services
AIL_DLS_open | opens a handle to a downloadable sample device.
AIL_DLS_close | closes a previously opened DLS device.
MILES_DLS_CLOSE_FLAGS | specifies optional closing flags to AIL_DLS_close.
AIL_DLS_load_file | loads an uncompressed DLS file into the specified DLS device.
AIL_DLS_load_memory | loads an uncompressed DLS file memory image into the specified DLS device.
AIL_DLS_unload | unloads a previously loaded DLS file ID and makes the sample memory available for other DLS files.
MILES_DLS_UNLOAD | describes optional DLS unload flags.
AIL_DLS_compact | compacts the memory of a hardware DLS device.
AIL_DLS_get_info | retrieves information about the specified DLS device.
AILDLSINFO | specifies the details for a DLS device.
AIL_DLS_sample_handle | returns the underlying HSAMPLE associated with a given DLS synthesizer instance.


AIL_DLS_open

The function AIL_DLS_open opens a handle to a downloadable sample device.

HDLSDEVICE AIL_DLS_open(
  HMDIDRIVER mdi,
  HDIGDRIVER dig,
  char const * DLS_dll_name,
  U32 flags,
  U32 rate,
  U32 bits,
  U32 channels
);

In Parameters

mdi
indicates the Miles MIDI handle that will be used for the DLS playback (this is only necessary for the software synthesizer).
dig
indicates the Miles digital sound handle that will be used for the DLS playback (this is only necessary for the software synthesizer).
DLS_dll_name
indicates the DLS provider DLL name to use. This should be NULL for the software synthesizer, "S3BASE.DLL" for the Sonic Vibes hardware DLS card, or "VORT_DLS.DLL" for Aureal Vortex DLS cards. In the future, RAD plans to create other DLS provider DLLs, so you should have some method for your application to accept new DLS provider filenames.
flags
should currently be zero.
rate
indicates the rate that the software synthesizer should use. Note that you don't have to match the output rate of the digital driver, so if you need to improve performance, you can slow down the digital MIDI synthesis without affecting the sound quality of the rest of the game. You should generally use the same rate that the DLS file's samples use, and you shouldn't run the synthesizer any faster than the digital driver is running.
bits
indicates the bit quality to use for the software synthesizer (8 or 16 bits). Note that switching from 16-bit output mode to 8-bit output mode won't improve performance all that much. You should generally use the same bit size that the DLS file's samples use, and you shouldn't run the synthesizer in 16-bit mode if the digital driver is in 8-bit mode.
channels
indicates the number of channels to use for the software synthesizer (1 is mono, 2 is stereo). Running the software synthesizer in mono mode increases performance, but you will lose any intended stereo effects in the sequence. You shouldn't run the synthesizer in stereo mode if the digital driver is in mono.

Returns

The DLS device handle to be used with the other Miles DLS functions.

Discussion

Hardware systems are usually very limited in amount of DLS memory that you can use. In fact, to be DLS-1 compatible, a DLS synthesizer need only provide 512K of memory.

In the future, RAD plans to create other DLS provider DLLs, so you should have some method for your application to accept new DLS provider filenames.

The higher the quality of the sound, the higher the CPU usage. If you plan to support a wide range of CPUs, then you should provide a method of allowing the performance to be scaled (from 11Khz, mono, 8-bit with no filtering and no reverb up to 44 Khz, stereo, 16-bit with filtering and reverb). You can use the Miles Sound Player to gauge the performance hit of the various options with your own sequences.

Group: DLS Services
Related Functions: AIL_DLS_close, AIL_quick_handles
Related Basic Types: HDIGDRIVER, HDLSDEVICE, HMDIDRIVER, MILES_OPEN_XMIDI_FLAGS, MILES_PREFERENCES, U32, char const *
Related FAQs: How do I play an XMIDI file with a DLS instrument set?


AIL_DLS_close

The function AIL_DLS_close closes a previously opened DLS device.

void AIL_DLS_close(
  HDLSDEVICE dls,
  U32 flags
);

In Parameters

dls
indicates the DLS device to close.
flags
is 0 or one or more of the MILES_DLS_CLOSE_FLAGS flags.

Discussion

You should usually just use 0 for the flags parameter and allow the DLS provider DLL to decide what to do at shutdown. The flags parameter is ignored by the software synthesizer DLS samples in the software synthesizer are always closed.

Group: DLS Services
Related Functions: AIL_DLS_open
Related Basic Types: HDLSDEVICE, MILES_DLS_CLOSE_FLAGS, U32, void


MILES_DLS_CLOSE_FLAGS

The basic type MILES_DLS_CLOSE_FLAGS specifies optional closing flags to AIL_DLS_close.

Fundamental Values

Value | Description
RETAIN_DLS_COLLECTION | retain the DLS data that was downloaded.
RETURN_TO_BOOTUP_STATE | return the DLS hardware to its default boot up state.
RETURN_TO_GM_ONLY_STATE | return the DLS hardware to General MIDI mode.
DLS_COMPACT_MEMORY | after unloading, compact the hardware memory.

Group: DLS Services
Related Functions: AIL_DLS_close


AIL_DLS_load_file

The function AIL_DLS_load_file loads an uncompressed DLS file into the specified DLS device.

HDLSFILEID AIL_DLS_load_file(
  HDLSDEVICE dls,
  char const * filename,
  U32 flags
);

In Parameters

dls
indicates the DLS device to load the DLS data into.
filename
is the name of the DLS file to use.
flags
should currently be zero.

Returns

A handle to a DLS file ID that can be used to unload the DLS data with the AIL_DLS_unload function, or NULL if the load was unsuccessful.

Discussion

This function only accepts uncompressed DLS files. If you have a compressed MLS file to load, use the AIL_extract_DLS function to get a DLS memory image and then load it with the AIL_DLS_load_memory function. You can use the AIL_file_type function to see what type of DLS file you have.

To load a DLS file that has been embedded in an XMI file, you can use the AIL_find_DLS function for uncompressed embedded DLS data, or the AIL_extract_DLS function for compressed embedded DLS data. You can use the AIL_file_type function to see what type of XMI file you have.

The software synthesizer will continue to use sample memory from the DLS file until the DLS device is closed, or the file ID is unloaded with the AIL_DLS_unload function.

The AIL_DLS_load_file function will always replace the existing DLS data when two DLS files specify duplicate instrument and note parameters.

Group: DLS Services
Related Functions: AIL_DLS_compact, AIL_DLS_load_file, AIL_DLS_load_memory, AIL_DLS_unload, AIL_compress_DLS, AIL_extract_DLS, AIL_file_type, AIL_find_DLS
Related Basic Types: HDLSDEVICE, HDLSFILEID, U32, char const *


AIL_DLS_load_memory

The function AIL_DLS_load_memory loads an uncompressed DLS file memory image into the specified DLS device.

HDLSFILEID AIL_DLS_load_memory(
  HDLSDEVICE dls,
  void const * memory,
  U32 flags
);

In Parameters

dls
indicates the DLS device to load the DLS data into.
memory
is the address of the in-memory DLS file image.
flags
should currently be zero.

Returns

A handle to a DLS file ID that can be used to unload the DLS data with the AIL_DLS_unload function, or NULL if the load was unsuccessful.

Discussion

Early releases of the Sonic Vibes DLS provider DLL did not support this function, so with older versions of the DLL, MSS will copy the entire supplied image out to a disk file and then call the AIL_DLS_load_file function. The latest S3 loader DLL can be found in the WINTOOLS subdirectory.

The Aureal Vortex DLS support has problems with from-memory loading, so MSS emulates this function by copying your memory image to a temporary file and then instructs the Aureal driver load from this temporary file. This means DLS from memory loading is a little slow with the Vortex driver.

You must not free the memory passed to AIL_DLS_load_memory unless the DLS device has been closed or the file ID has been unloaded first.

This function only accepts uncompressed DLS files. If you have a compressed MLS file to load, use the AIL_extract_DLS function to get a DLS memory image and then load it with this function. You can use the AIL_file_type function to see what type of DLS file you have.

To load a DLS file that has been embedded in an XMI file, you can use the AIL_find_DLS function for uncompressed embedded DLS data, or the AIL_extract_DLS function for compressed embedded DLS data. You can use the AIL_file_type function to see what type of XMI file you have.

The software synthesizer will continue to use sample memory from the DLS file until the DLS device is closed, or the file ID is unloaded with the AIL_DLS_unload function.

The AIL_DLS_load_memory function will always replace the existing DLS data when two DLS files specify duplicate instrument and note parameters.

Group: DLS Services
Related Functions: AIL_DLS_compact, AIL_DLS_load_file, AIL_DLS_load_memory, AIL_DLS_unload, AIL_extract_DLS, AIL_file_type, AIL_find_DLS
Related Basic Types: HDLSDEVICE, HDLSFILEID, U32, void const *
Related FAQs: How do I play an XMIDI file with a DLS instrument set?


AIL_DLS_unload

The function AIL_DLS_unload unloads a previously loaded DLS file ID and makes the sample memory available for other DLS files.

void AIL_DLS_unload(
  HDLSDEVICE dls,
  HDLSFILEID dlsid
);

In Parameters

dls
indicates the DLS device to unload the DLS data from.
dlsid
indicates the file ID from AIL_DLS_load_file or AIL_DLS_load_memory to unload, or one of the MILES_DLS_UNLOAD constants.

Discussion

After freeing DLS memory from a hardware device, you may have to call AIL_DLS_compact before you can load new DLS data.

Always unload DLS memory passed to AIL_DLS_load_memory, with this function before freeing the memory itself.

Group: DLS Services
Related Functions: AIL_DLS_compact, AIL_DLS_load_file, AIL_DLS_load_memory
Related Basic Types: HDLSDEVICE, HDLSFILEID, MILES_DLS_UNLOAD, void


MILES_DLS_UNLOAD

The basic type MILES_DLS_UNLOAD describes optional DLS unload flags.

Fundamental Values

Value | Description
AIL_DLS_UNLOAD_MINE | unload all DLS data that this application has loaded.
AIL_DLS_UNLOAD_ALL | unload all DLS data loaded by any application.

Group: DLS Services
Related Functions: AIL_DLS_unload


AIL_DLS_compact

The function AIL_DLS_compact compacts the memory of a hardware DLS device.

void AIL_DLS_compact(
  HDLSDEVICE dls
);

In Parameters

dls
indicates the DLS device to compact the DLS memory for.

Discussion

Hardware devices aren't always very good at handling their memory, so if a call to AIL_DLS_load_file or AIL_DLS_load_memory fails, then you may want to call this function and then try the load again.

Group: DLS Services
Related Functions: AIL_DLS_load_file, AIL_DLS_load_memory, AIL_DLS_unload
Related Basic Types: HDLSDEVICE, void


AIL_DLS_get_info

The function AIL_DLS_get_info retrieves information about the specified DLS device.

void AIL_DLS_get_info(
  HDLSDEVICE dls,
  AILDLSINFO *info,
  S32 *PercentCPU
);

In Parameters

dls
indicates the DLS device to query.

Out Parameters

info
is an address of an AILDLSINFO structure that will contain the DLS info.
PercentCPU
is a pointer to an integer that will contain the percentage of CPU that the software synthesizer is using since the last call to AIL_DLS_get_info.

Group: DLS Services
Related Functions: AIL_DLS_get_info
Related Basic Types: HDLSDEVICE, S32, void
Related Structures: AILDLSINFO


AILDLSINFO

The structure AILDLSINFO specifies the details for a DLS device.

struct AILDLSINFO
{
  S32 MaxDLSMemory;
  S32 CurrentDLSMemory;
  S32 LargestSize;
  S32 GMAvailable;
  S32 GMBankSize;
};

In Members

MaxDLSMemory
Maximum amount of DLS memory available. Always 2 GB with the software synth.
CurrentDLSMemory
Current amount of memory dedicated to DLS use. Always 2 GB with the software synth.
LargestSize
Largest DLS file that could be loaded right now. Always 2 GB with the software synth.
GMAvailable
General MIDI availability status. Not applicable to the software synth.
GMBankSize
Size of the General MIDI set. Not applicable to the software synth.

Group: DLS Services
Related Functions: AIL_DLS_get_info
Related Basic Types: S32


AIL_DLS_sample_handle

The function AIL_DLS_sample_handle returns the underlying HSAMPLE associated with a given DLS synthesizer instance.

HSAMPLE AIL_DLS_sample_handle(
  HDLSDEVICE dls
);

In Parameters

dls
indicates the DLS device whose HSAMPLE should be returned.

Returns

The HSAMPLE used by the synthesizer instance to render DLS instrument output.

Discussion

In MSS 7, a number of redundant functions were replaced with this accessor function. If your application previously called AIL_DLS_set_reverb_levels, AIL_DLS_get_reverb_levels, AIL_DLS_processor, AIL_set_DLS_processor, AIL_filter_DLS_attribute, or AIL_set_filter_DLS_preference, it should be modified to call the HSAMPLE-based version of those functions after obtaining the DLS synthesizer's underlying HSAMPLE via AIL_DLS_sample_handle.

Group: DLS Services
Related Functions: AIL_DLS_sample_handle
Related Basic Types: HDLSDEVICE, HSAMPLE
Related FAQs: How do I apply a low-pass filter?, I used an older version of Miles and now my volume and pan calls are weird - what's going on? And what's with the two types of volume functions?, What's the best way to port my older Miles application to MSS 7?


Utility Services

Discussion

provide many functions that used to be standalone utilities in previous versions of the Miles Sound System. Now that this technology is available as part of the general MSS library, you can add some neat new features to your applications. You could, for example, leave your MIDI sequences in standard MIDI formatted files and only convert them to XMIDI at playback time. This would let your users edit and add new MIDI files to your application!

These functions were used to create the new Miles Sound Studio application. The source code for this utility (found in \src\tools) is an excellent place to look for sophisticated examples of these functions.

Note that you may never have to even use any of these functions, since many can be performed offline with the Miles Sound Studio.

Utility Services
AIL_file_type | returns the file type of the specified file image.
MILES_FILE_TYPE | describes the type of a file.
AIL_file_type_named | returns the file type of the specified file image using a filename hint.
AIL_WAV_info | retrieves the audio format information for the specified file image.
AILSOUNDINFO | specifies audio format details.
AIL_process_digital_audio | provides high-level access to the Miles sound mixer.
AILMIXINFO
AIL_size_processed_digital_audio | provides a way to determine how much output memory is necessary for a given set of input mix data.
AIL_compress_ADPCM | compresses the digital sound described by the info structure into an IMA ADPCM wave file image.
AIL_decompress_ADPCM | decompresses the IMA ADPCM digital sound described by the info structure into a standard PCM wave file image.
AIL_compress_ASI | compresses a digital sound with an ASI encoder capable of writing the file type described by the filename_ext parameter.
AILLENGTHYCB | specifies a user-defined callback that gets called during lengthy Miles operations.
MILES_LENGTHY_STATE | indicates the current stage of the lengthy operation.
AILCODECSETPROP | provides a way for ASI properties to be set during a compression or decompression.
AIL_decompress_ASI | decompresses a digital sound with the ASI decoder for the passed file extension and returns a standard PCM wave file image.
AIL_MIDI_to_XMI | converts Standard MIDI Format 0 and Format 1 sequence files to the Extended MIDI (XMIDI) format.
MILES_MIDI_TO_XMI_FLAGS | specifies optional conversion flags for the AIL_MIDI_to_XMI function.
AIL_compress_DLS | compresses a DLS file with either IMA ADPCM compression or with an ASI encoder specified by the compress_ext parameter.
AIL_extract_DLS | extracts and decompresses the DLS data from a loaded MLS file or merged XMIDI file.
AIL_find_DLS | returns pointers and sizes to the DLS and XMIDI chunks inside a merged XMIDI file image.
AIL_merge_DLS_with_XMI | merges an XMIDI file and a DLS or MLS file together.
AIL_filter_DLS_with_XMI | filters out unused instruments in a DLS file given one or more XMIDI files.
MILES_FILTER_DLS_FLAGS | specifies options to use when filtering DLS instrument sets with an XMIDI file.
AIL_list_MIDI | creates a detailed listing of a MIDI file.
MILES_LIST_MIDI_FLAGS | specifies flags to use when listing a MIDI file.
AIL_list_DLS | creates a detailed listing of a DLS or MLS file.
MILES_LIST_DLS_FLAGS | specifies flags to use when listing a DLS file.
AIL_inspect_MP3 | obtains some basic information about the structure of an MPEG-1 Layer 3 audio file, and prepares for optional header enumeration.
AIL_enumerate_MP3_frames | obtains information about successive frames from an MPEG-1 Layer 3 audio file.
MP3_INFO


AIL_file_type

The function AIL_file_type returns the file type of the specified file image.

S32 AIL_file_type(
  void const * data,
  U32 size
);

In Parameters

data
points to a buffer containing the file that you're interested in.
size
is the length of the file image.

Returns

One of the MILES_FILE_TYPE constants.

Group: Utility Services
Related Functions: AIL_DLS_load_file, AIL_DLS_load_memory, AIL_extract_DLS, AIL_file_type_named, AIL_find_DLS
Related Basic Types: MILES_FILE_TYPE, S32, U32, void const *
Related FAQs: How do I play an XMIDI file with a DLS instrument set?


MILES_FILE_TYPE

The basic type MILES_FILE_TYPE describes the type of a file.

Fundamental Values

Value | Description
AILFILETYPE_UNKNOWN | File isn't one of the supported types. (Debugger value: 0).
AILFILETYPE_PCM_WAV | Standard PCM wave file. (Debugger value: 1).
AILFILETYPE_ADPCM_WAV | IMA ADPCM compressed wave file. (Debugger value: 2).
AILFILETYPE_OTHER_WAV | Unsupported compressed wave file. (Debugger value: 3).
AILFILETYPE_OTHER_ASI_WAV | Compressed wave file that is handled by an unspecified ASI decoder. (Debugger value: 14).
AILFILETYPE_VOC | Creative VOC digital sound file. (Debugger value: 4).
AILFILETYPE_MIDI | Standard MIDI file. (Debugger value: 5).
AILFILETYPE_XMIDI | XMIDI file. (Debugger value: 6).
AILFILETYPE_XMIDI_DLS | XMIDI file containing embedded, uncompressed DLS data. (Debugger value: 7).
AILFILETYPE_XMIDI_MLS | XMIDI file containing embedded, compressed DLS data. (Debugger value: 8).
AILFILETYPE_DLS | Uncompressed DLS file. (Debugger value: 9).
AILFILETYPE_MLS | Compressed DLS file. (Debugger value: 10).
AILFILETYPE_MPEG_L1_AUDIO | Compressed MPEG Layer 1 file (which MSS cannot play). (Debugger value: 11).
AILFILETYPE_MPEG_L2_AUDIO | Compressed MPEG Layer 2 file (which MSS cannot play). (Debugger value: 12).
AILFILETYPE_MPEG_L3_AUDIO | Compressed MPEG Layer 3 file. (Debugger value: 13).
AILFILETYPE_OTHER_ASI_WAV | An unspecified .WAV-wrapped format supported by an MSS ASI decoder. (Debugger value: 14).
AILFILETYPE_XBOX_ADPCM_WAV | XBOX ADPCM compressed wave file. (Debugger value: 15).
AILFILETYPE_OGG_VORBIS | Compressed Ogg Vorbis file. (Debugger value: 16).
AILFILETYPE_V12_VOICE | Compressed Voxware V12 voice codec compressed file. (Debugger value: 17).
AILFILETYPE_V24_VOICE | Compressed Voxware V24 voice codec compressed file. (Debugger value: 18).
AILFILETYPE_V29_VOICE | Compressed Voxware V29 voice codec compressed file. (Debugger value: 19).

Group: Utility Services
Related Functions: AIL_file_type, AIL_file_type_named


AIL_file_type_named

The function AIL_file_type_named returns the file type of the specified file image using a filename hint.

S32 AIL_file_type_named(
  void const * data,
  char const * filename,
  U32 size
);

In Parameters

data
points to a buffer containing the file that you're interested in.
filename
specifies the filename of the data loaded in the data parameter.
size
is the length of the file image.

Returns

One of the MILES_FILE_TYPE constants.

Discussion

This function is the same as AIL_file_type, except that it takes a filename hint to identify more file types (like Voxware voice compressed data).

Group: Utility Services
Related Functions: AIL_file_type
Related Basic Types: MILES_FILE_TYPE, S32, U32, char const *, void const *


AIL_WAV_info

The function AIL_WAV_info retrieves the audio format information for the specified file image.

S32 AIL_WAV_info(
  void const * data,
  AILSOUNDINFO *info
);

In Parameters

data
points to a buffer containing the wave file image.

Out Parameters

info
is a pointer to an AILSOUNDINFO structure that will return the wave information.

Returns

1, if the call was successful, or 0 if the call failed.

Discussion

This function can be used to load the info structure that is needed in the AIL_compress_ADPCM and AIL_decompress_ADPCM functions.

The channel_mask member corresponds to the dwChannelMask member of the WAVEFORMATEXTENSIBLE header defined by Microsoft. See the How do I use multi-channel sound output in Miles? FAQ for more on multichannel content authoring and channel masks.

Group: Utility Services
Related Functions: AIL_compress_ADPCM, AIL_compress_ASI, AIL_decompress_ADPCM, AIL_process_digital_audio, AIL_set_sample_adpcm_block_size, AIL_set_sample_info, AIL_size_processed_digital_audio
Related Basic Types: S32, void const *
Related Structures: AILMIXINFO, AILSOUNDINFO
Related FAQs: How do I use multi-channel sound output in Miles?


AILSOUNDINFO

The structure AILSOUNDINFO specifies audio format details.

struct AILSOUNDINFO
{
  S32 format;
  void * data_ptr;
  U32 data_len;
  U32 rate;
  S32 bits;
  S32 channels;
  U32 channel_mask;
  U32 samples;
  U32 block_size;
};

In Members

format
Contains the format constant - MSS supported values are WAVE_FORMAT_PCM for standard, uncompressed wave files and WAVE_FORMAT_IMA_ADPCM for IMA ADPCM compressed wave files.
data_ptr
Contains a pointer to the beginning of the sound data in the wave file.
data_len
Contains the length of the sound data in the wave file.
rate
Contains the playback rate of the wave file.
bits
Contains the bit depth of the sound data (usually 4, 8, or 16).
channels
Contains the number of channels in the wave file (1 is mono, 2 is stereo).
channel_mask
Specifies the Microsoft WDM-compatible 32-bit channel mask for multichannel samples, or ~0U for traditional mono or stereo samples. See the How do I use multi-channel sound output in Miles? FAQ for more information on channel masks and multichannel content authoring.
samples
Contains the total number of samples in the wave file (used with ADPCM).
block_size
Contains the IMA ADPCM block size.

Group: Utility Services
Related Functions: AIL_WAV_info, AIL_compress_ADPCM, AIL_compress_ASI, AIL_decompress_ADPCM, AIL_process_digital_audio, AIL_set_sample_info, AIL_size_processed_digital_audio
Related Basic Types: S32, U32, void *
Related Structures: AILMIXINFO
Related FAQs: How do I use multi-channel sound output in Miles?


AIL_process_digital_audio

The function AIL_process_digital_audio provides high-level access to the Miles sound mixer.

S32 AIL_process_digital_audio(
  void *dest,
  S32 destsize,
  U32 destrate,
  U32 destformat,
  S32 num_srcs,
  AILMIXINFO const * const *srcs
);

In Parameters

destsize
contains the size of the output buffer. If the mixer fills the output buffer, then it will return (allowing you to calling again and again until the source data is exhausted).
destrate
contains the output data rate that you want the destination buffer to be mixed to.
destformat
contains the format that you want the destination buffer to be mixed to. See the MILES_DIGITAL_FORMAT flags for the possible output formats.
num_srcs
contains the number of buffers that you want to mix. If you don't want to mix multiple samples, then just pass 1 for this parameter.
srcs
is a pointer to an array of "num_srcs" AILMIXINFO structures. The only part of the AILMIXINFO structure that you need to set is the Info structure inside the AILMIXINFO structure. The Info structure is of type AILSOUNDINFO, so you can use AIL_WAV_info to set the appropriate fields. See the example below for details.

Out Parameters

dest
points to the output buffer.

Returns

The number of bytes mixed if the call was successful, or 0 if the call failed.

Discussion

You can use this function to mix one or more samples together, perform sample rate conversions - basically anything that the Miles mixer can do!

This function modifies the srcs data structures, so that you can call it over and over mixing the next pieces of the input data each call (this is handy when mixing through a small destination buffer.

This function can directly accept IMA ADPCM compressed data, but not MPEG Layer 3 or other ASI-compressed data.

Multichannel (> 2 channels) data is not supported.

You can use the AIL_WAV_info function to automatically fill the input src->Info structures. However, the output data is raw data, so you should use AIL_WAV_file_write if you need to write the output data in wave format.

Example: The following example will mix two wave files together and write out the result:

void* in1, * in2, * out;
AILMIXINFO mix[2];
U32 outsize, mixsize;
In1=AIL_file_read("file1.wav",0);
In2=AIL_file_read("file2.wav",0);
AIL_WAV_info(in1,&mix[0].Info);
AIL_WAV_info(in2,&mix[1].Info);
outsize=AIL_size_processed_digital_audio(44100,DIG_F_MONO_16,2,mix);
out=AIL_mem_alloc_lock(outsize);
mixsize=AIL_process_digital_audio(out,outsize,44100,DIG_F_MONO_16,2,mix);
AIL_WAV_file_write("mixed.wav",out,mixsize,44100,DIG_F_MONO_16);

Group: Utility Services
Related Functions: AIL_WAV_file_write, AIL_WAV_info, AIL_scratchpad_policy, AIL_set_scratchpad_policy, AIL_size_processed_digital_audio
Related Basic Types: MILES_DIGITAL_FORMAT, MSS_RESOURCE_POLICY, S32, U32, void
Related Structures: AILMIXINFO, AILSOUNDINFO
Related FAQs: How can I assign 3D positions to stereo samples?


AILMIXINFO

struct AILMIXINFO
{
  AILSOUNDINFO Info;
};

In Members

Info
Contains the details on each audio buffer that you'd like to mix together.

Discussion

The only part of the AILMIXINFO structure that you need to set is the Info structure inside the AILMIXINFO structure. The Info structure is of type AILSOUNDINFO, so you can use AIL_WAV_info to set the appropriate fields. See the example below for details.

Group: Utility Services
Related Functions: AIL_WAV_info, AIL_process_digital_audio, AIL_size_processed_digital_audio
Related Structures: AILMIXINFO, AILSOUNDINFO


AIL_size_processed_digital_audio

The function AIL_size_processed_digital_audio provides a way to determine how much output memory is necessary for a given set of input mix data.

S32 AIL_size_processed_digital_audio(
  U32 destrate,
  U32 destformat,
  S32 num_srcs,
  AILMIXINFO const * const *srcs
);

In Parameters

destrate
contains the output data rate that you will be mixing to.
destformat
contains the format that you want the destination buffer to be mixed to. See the MILES_DIGITAL_FORMAT flags for the possible output formats.
num_srcs
contains the number of buffers that you will be mixing. If you won't be mixing multiple samples, then just pass 1 for this parameter.
srcs
is a pointer to an array of "num_srcs" AILMIXINFO structures. The only part of the AILMIXINFO structure that you need to set is the Info structure inside the AILMIXINFO structure. The Info structure is of type AILSOUNDINFO, so you can use AIL_WAV_info to set the appropriate fields. See the example in AIL_process_digital_audio for details.

Returns

The number of bytes that will be necessary to completely perform the mix.

Discussion

You can use the AIL_WAV_info function to automatically fill the input src->Info structures.

Multichannel (> 2 channels) data is not supported.

This function can directly accept IMA ADPCM compressed data, but not MPEG Layer 3 or other ASI-compressed data.

Group: Utility Services
Related Functions: AIL_WAV_info, AIL_process_digital_audio
Related Basic Types: MILES_DIGITAL_FORMAT, S32, U32
Related Structures: AILMIXINFO, AILSOUNDINFO


AIL_compress_ADPCM

The function AIL_compress_ADPCM compresses the digital sound described by the info structure into an IMA ADPCM wave file image.

S32 AIL_compress_ADPCM(
  AILSOUNDINFO const *info,
  void * *wav,
  U32 *wavesize
);

In Parameters

info
describes the sound data to compress.

Out Parameters

wav
should be the address of a " void* " pointer that will return with the pointer to the new wave file image. This parameter can be NULL if you don't need it.
wavesize
should be the address of an unsigned 32-bit integer that will return the size of the new wave file image. This parameter can be NULL if you don't need it.

Returns

1, if the call was successful, or 0 if the call failed.

Discussion

You must free the pointer returned in wav with AIL_mem_free_lock.

You can use the AIL_WAV_info function to automatically fill the input info structure.

Multichannel (> 2 channels) data is not supported.

The output wave file image is a standard IMA ADPCM wave file - you can write it directly to disk and any WAV file player will be able to play it.

Group: Utility Services
Related Functions: AIL_WAV_info, AIL_compress_ASI, AIL_decompress_ADPCM, AIL_mem_free_lock
Related Basic Types: S32, U32, void *
Related Structures: AILSOUNDINFO
Related FAQs: I'm getting a glitch when I loop an MP3 or ADPCM file - what can I do?


AIL_decompress_ADPCM

The function AIL_decompress_ADPCM decompresses the IMA ADPCM digital sound described by the info structure into a standard PCM wave file image.

S32 AIL_decompress_ADPCM(
  AILSOUNDINFO const *info,
  void * *wav,
  U32 *wavesize
);

In Parameters

info
describes the ADCPM sound data to decompress.

Out Parameters

wav
should be the address of a " void* " pointer that will return with the pointer to the new wave file image. This parameter can be NULL if you don't need it.
wavesize
should be the address of an unsigned 32-bit integer that will return with the size of the new wave file image. This parameter can be NULL if you don't need it.

Returns

1, if the call was successful, or 0 if the call failed.

Discussion

You must free the pointer returned in wav with AIL_mem_free_lock.

Multichannel (> 2 channels) data is not supported.

You can use the AIL_WAV_info function to automatically fill the input info structure.

The output wave file image is a standard PCM wave file - you can write it directly to disk and any WAV file player will be able to play it.

Group: Utility Services
Related Functions: AIL_WAV_info, AIL_compress_ADPCM, AIL_decompress_ASI, AIL_mem_free_lock
Related Basic Types: S32, U32, void *
Related Structures: AILSOUNDINFO


AIL_compress_ASI

The function AIL_compress_ASI compresses a digital sound with an ASI encoder capable of writing the file type described by the filename_ext parameter.

S32 AIL_compress_ASI(
  AILSOUNDINFO const *info,
  char const * filename_ext,
  void * *outdata,
  U32 *outsize,
  AILLENGTHYCB callback
);

In Parameters

info
describes the sound data to compress.
filename_ext
is a filename whose extension determines what ASI codec to use. For example, to use the MPEG Layer 3 encoder, you would specify ".mp3". The Miles voice chat codecs use extensions of ".v29", ".v24", and ".v12". Future encoders will have their own extensions.
callback
should be set to the address of the callback function of the AILLENGTHYCB type. Pass 0 if callbacks are not necessary.

Out Parameters

outdata
should be the address of a " void* " pointer that will return with the pointer to the new compressed file image. This parameter can be NULL if you don't need it.
outsize
should be the address of an unsigned 32-bit integer that will return with the size of the compressed file image. This parameter can be NULL if you don't need it.

Returns

1, if the call was successful, or 0 if the call failed.

Discussion

Note that the only MSS ASI encoder currently available is the MSS MPEG Layer 3 encoder, and it must be purchased separately (in addition, it isn't redistributable). We plan to have more audio ASI encoders soon (including a Bink audio codec).

Multichannel (> 2 channels) data is not supported.

You must free the pointer returned in outdata with AIL_mem_free_lock.

You can use the AIL_WAV_info function to automatically fill the input info structure.

Compressing with the MSS MPEG Layer 3 encoder is very slow!

Group: Utility Services
Related Functions: AILLENGTHYCB, AIL_WAV_info, AIL_compress_ADPCM, AIL_decompress_ASI, AIL_mem_free_lock
Related Basic Types: S32, U32, char const *, void *
Related Structures: AILSOUNDINFO


AILLENGTHYCB

The function AILLENGTHYCB specifies a user-defined callback that gets called during lengthy Miles operations.

S32 AILCALLBACK AILLENGTHYCB(
  U32 state,
  UINTa value
);

In Parameters

state
indicates the current callback state. It will be set to one of the MILES_LENGTHY_STATE constants.
value
provides an extra value to the callback. This value has different meaning depending on the state variable.

Returns

Your callback should return zero to cancel the callback, or non-zero to continue processing.

Group: Utility Services
Related Functions: AILCODECSETPROP, AIL_compress_ASI, AIL_compress_DLS, AIL_decompress_ASI, AIL_extract_DLS, AIL_filter_DLS_with_XMI
Related Basic Types: MILES_LENGTHY_STATE, S32, U32, UINTa


MILES_LENGTHY_STATE

The basic type MILES_LENGTHY_STATE indicates the current stage of the lengthy operation.

Fundamental Values

Value | Description
AIL_LENGTHY_INIT | This state means that the process is about to begin. This let's you set up any persistent variables that you might need.
AIL_LENGTHY_SET_PROPERTY | This state is called to allow you to set codec properties. The value parameter contains an address of a function of the AILCODECSETPROP type. So, to set a property, you cast the value parameter to AILCODECSETPROP and then perform the function call. You would use code something like this: ((AILCODECSETPROP)value) ( "Requested Bit Rate", 64 ); The Miles MPEG properties that you can use are listed with the AILCODECSETPROP definition.
AIL_LENGTHY_UPDATE | Your callback will be called many times with this state during a long operation. The value parameter is the percentage of completion. The percentage is an F32, so you must cast the value to get the correct percentage - use something like: F32 percent=*(F32*)&value; You will usually cancel a long operation by returning a zero from this callback.
AIL_LENGTHY_DONE | This state means that the process is completed and you can free any persistent variables. The value parameter isn't used and the return value from this callback is ignored.

Group: Utility Services
Related Functions: AILCODECSETPROP, AILLENGTHYCB


AILCODECSETPROP

The function AILCODECSETPROP provides a way for ASI properties to be set during a compression or decompression.

S32 AILCODECSETPROP(
  char const * property,
  void const * value
);

In Parameters

property
indicates the property name to set.
value
indicates the value to set the property to.

Returns

1 if the property set was successful, 0 if the property set failed.

Discussion

This function address is provided in the value parameter of the AILLENGTHYCB function when the AIL_LENGTHY_SET_PROPERTY state is passed.

The Miles MPEG encoder defines the following properties:

"Requested bit rate": which specifies the output bit rate to use in kilobits per second - you may use: 32,40,48,56,64,80,96,112,128,160,192,224,256,320).

"Requested sample rate": which specifies the output playback (for MPEG I Layer 3, this means 32000, 44100, or 48000 Hz).

"Requested # of channels": which is the number of output channels (1 for mono, 2 for stereo).

Group: Utility Services
Related Functions: AILLENGTHYCB
Related Basic Types: MILES_LENGTHY_STATE, S32, char const *, void const *


AIL_decompress_ASI

The function AIL_decompress_ASI decompresses a digital sound with the ASI decoder for the passed file extension and returns a standard PCM wave file image.

S32 AIL_decompress_ASI(
  void const * indata,
  U32 insize,
  char const * filename_ext,
  void * *wav,
  U32 *wavesize,
  AILLENGTHYCB callback
);

In Parameters

indata
contains the compressed input data.
insize
is the length of the compressed data in bytes.
filename_ext
is a filename whose extension determines what ASI decoder to use. For example, to use the MPEG Layer 3 decoder, you would specify ".mp3". The Miles voice chat codecs use extensions of ".v29", ".v24", and ".v12". Future decoders will have their own extensions.
callback
should be set to the address of the callback function which is invoked at several stages of the decompression process. See AIL_compress_ASI for a description of this callback.

Out Parameters

wav
should be the address of a " void* " pointer that will return with the pointer to the new wave file image. This parameter can be NULL if you don't need it.
wavesize
should be the address of an unsigned 32-bit integer that will return with the size of the new wave file image. This parameter can be NULL if you don't need it.

Returns

1, if the call was successful, or 0 if the call failed.

Discussion

You must free the pointer returned in wav with AIL_mem_free_lock.

The output wave file image is a standard PCM wave file - you can write it directly to disk and any WAV file player will be able to play it.

Group: Utility Services
Related Functions: AILLENGTHYCB, AIL_compress_ASI, AIL_decompress_ADPCM, AIL_mem_free_lock
Related Basic Types: S32, U32, char const *, void *, void const *


AIL_MIDI_to_XMI

The function AIL_MIDI_to_XMI converts Standard MIDI Format 0 and Format 1 sequence files to the Extended MIDI (XMIDI) format.

S32 AIL_MIDI_to_XMI(
  void const * MIDI,
  U32 MIDI_size,
  void * *XMI,
  U32 *XMI_size,
  S32 flags
);

In Parameters

MIDI
points to a file image containing standard MIDI data.
MIDI_size
is the length of the MIDI data.
flags
is zero, or one or more of the MILES_MIDI_TO_XMI_FLAGS.

Out Parameters

XMI
should be the address of a " void* " pointer that will return with the pointer to the new XMIDI file image. This parameter can be NULL if you don't need it.
XMI_size
should be the address of an unsigned 32-bit integer that will return with the size of the new XMIDI file image. This parameter can be NULL if you don't need it.

Returns

1, if the call was successful, or 0 if the call failed.

Discussion

You must free the pointer returned in XMI with AIL_mem_free_lock.

This function will convert Standard MIDI Format 0 and Format 1 sequence files to the Extended MIDI (XMIDI) format used by the Miles Sound System's Version 2.0 and Version 3.0 drivers. This conversion preserves all of the information needed to faithfully reproduce the sequence's original sound, while discarding elements of the MIDI storage format that are redundant, inefficient, or otherwise unnecessary for real-time playback.

An XMIDI file containing a single translated MIDI sequence often requires from 10% to 30% less storage space, and can be performed with substantially less background processing time. The MIDI data track is compressed mostly by the elimination of all Note Off messages, which is made possible by appending each note's duration in quantization intervals to its original Note On event. Track-specific MIDI meta-events (such as Sequence/Track Name, Instrument Name, and End of Track events) are stripped from the data stream, while a single End of Track meta-event (FF 2F 00) is placed at the end of the XMIDI sequence.

In addition to the prequantized MIDI event stream, the XMIDI sequence format also includes information such as master lists of Global Timbre Library entries needed by the sequence and target offsets for any Sequence Branch Index controllers present in the sequence. To aid developers with specialized needs, XMIDI files are stored in accordance with Electronic Arts' Interchange File Format (EA IFF 85) standard. For example, using conventional IFF access routines, MSS applications may load and interpret XMIDI timbre list (TIMB) chunks manually, using the data to prepare the synthesizer for immediate playback of sequences at a later time.

Refer to the Extended MIDI (XMIDI) Specification Section for a detailed description of the XMIDI IFF structure.

Group: Utility Services
Related Sections: Extended MIDI IFF (.XMI) Structure
Related Functions: AIL_init_sequence, AIL_mem_free_lock, AIL_sequence_position
Related Basic Types: MILES_MIDI_TO_XMI_FLAGS, MILES_PREFERENCES, S32, U32, void *, void const *
Related FAQs: How do I play an XMIDI or MIDI file?


MILES_MIDI_TO_XMI_FLAGS

The basic type MILES_MIDI_TO_XMI_FLAGS specifies optional conversion flags for the AIL_MIDI_to_XMI function.

Fundamental Values

Value | Description
AILMIDITOXMI_TOLERANT | tells Miles to ignore most common errors in the input MIDI file.
AILMIDITOXMI_USINGLIST | specifies that the MIDI_size parameter is ignored, and the MIDI parameter should point to a series of unsigned 32-bit integers, formatted as follows (this flag is used to covert a series of MIDI files into one XMIDI file): 1st U32 - number of MIDI files to convert 2nd U32 - pointer to the first MIDI file image. 3rd U32 - size of the first MIDI file image. 4th U32 - pointer to the second MIDI file image. 5th U32 - size of the second the MIDI file image. 6th U32 - pointer to the third MIDI file image. 7th U32 - size of the third MIDI file image. ... etc.

Group: Utility Services
Related Functions: AIL_MIDI_to_XMI


AIL_compress_DLS

The function AIL_compress_DLS compresses a DLS file with either IMA ADPCM compression or with an ASI encoder specified by the compress_ext parameter.

S32 AIL_compress_DLS(
  void const * dls,
  char const * compression_ext,
  void * *mls,
  U32 *mlssize,
  AILLENGTHYCB callback
);

In Parameters

dls
points to a file image containing the DLS file.
compression_ext
is a filename whose extension determines what ASI codec to use. For example, to use the MPEG Layer 3 encoder, you would specify ".mp3". Future encoders will have their own extensions. To use IMA ADPCM compression only, pass in NULL for this parameter.
callback
should be set to the address of the callback function which is invoked at several stages of the compression process. See AILLENGTHYCB for a description of this callback.

Out Parameters

mls
should be the address of a "void *" pointer that will return with the pointer to the new compressed DLS file image. This parameter can be NULL if you don't need it.
mlssize
should be the address of an unsigned 32-bit integer that will return with the size of the new compressed DLS file image. This parameter can be NULL if you don't need it.

Returns

1, if the call was successful, or 0 if the call failed.

Discussion

You must free the pointer returned in mls with AIL_mem_free_lock.

Depending on the number of wave samples to compress, this function can take up to 30 seconds to return.

Compressing a DLS file using the MPEG Layer 3 encoder takes a long time.

You must decompress DLS files with the AIL_extract_DLS function before passing them to AIL_DLS_load_file.

Compressed DLS file usually have an ".MLS" extension.

Group: Utility Services
Related Functions: AILLENGTHYCB, AIL_DLS_load_file, AIL_extract_DLS, AIL_find_DLS, AIL_mem_free_lock, AIL_merge_DLS_with_XMI
Related Basic Types: S32, U32, char const *, void *, void const *


AIL_extract_DLS

The function AIL_extract_DLS extracts and decompresses the DLS data from a loaded MLS file or merged XMIDI file.

S32 AIL_extract_DLS(
  void const * data,
  U32 size,
  void * *XMI,
  U32 *XMI_size,
  void * *dls,
  U32 *dlssize,
  AILLENGTHYCB callback
);

In Parameters

data
points to a file image containing an MLS file, or an XMIDI file with embedded DLS data.
size
is the length of the data.
callback
should be set to the address of the callback function which is invoked at several stages of the decompression process. See AILLENGTHYCB for a description of this callback.

Out Parameters

XMI
should be the address of a " void* " pointer that will return with the pointer to the new XMIDI file image. This parameter can be NULL if you don't need it.
XMI_size
should be the address of an unsigned 32-bit integer that will return with the size of the new XMIDI file image. This parameter can be NULL if you don't need it.
dls
should be the address of a " void* " pointer that will return with the pointer to the new uncompressed DLS file image. This parameter can be NULL if you don't need it.
dlssize
should be the address of an unsigned 32-bit integer that will return with the size of the new uncompressed DLS file image. This parameter can be NULL if you don't need it.

Returns

1, if the call was successful, or 0 if the call failed.

Discussion

This function returns copies of the XMIDI and DLS data - that is, you must call AIL_mem_free_lock on the returned XMIDI and DLS pointers. If you want to obtain direct pointers to the XMIDI and DLS chunks inside the original file image, you can use the AIL_find_DLS function.

A good way to decide whether to use AIL_extract_DLS or AIL_find_DLS is whether the DLS data is compressed. If the data is uncompressed, then you can pass it directly to AIL_DLS_load_memory, so AIL_find_DLS can be used. If the data is compressed, then you must decompress it with AIL_extract_DLS before handing it off to AIL_DLS_load_memory. You can determine whether the data is compressed or not with the AIL_file_type function.

Group: Utility Services
Related Functions: AILLENGTHYCB, AIL_DLS_load_file, AIL_DLS_load_memory, AIL_compress_DLS, AIL_extract_DLS, AIL_file_type, AIL_filter_DLS_with_XMI, AIL_find_DLS, AIL_mem_free_lock, AIL_merge_DLS_with_XMI
Related Basic Types: S32, U32, void *, void const *
Related FAQs: How do I play an XMIDI file with a DLS instrument set?


AIL_find_DLS

The function AIL_find_DLS returns pointers and sizes to the DLS and XMIDI chunks inside a merged XMIDI file image.

S32 AIL_find_DLS(
  void const * data,
  U32 size,
  void * *XMI,
  U32 *XMI_size,
  void * *dls,
  U32 *dlssize
);

In Parameters

data
points to a file image containing an XMIDI file with embedded DLS data.
size
is the length of the data.

Out Parameters

XMI
should be the address of a " void* " pointer that will return with the pointer to the XMIDI chunk. This parameter can be NULL if you don't need it.
XMI_size
should be the address of an unsigned 32-bit integer that will return with the size of the XMIDI chunk. This parameter can be NULL if you don't need it.
dls
should be the address of a " void* " pointer that will return with the pointer to the DLS or MLS chunk. This parameter can be NULL if you don't need it.
dlssize
should be the address of an unsigned 32-bit integer that will return with the size of the DLS or MLS chunk. This parameter can be NULL if you don't need it.

Returns

1, if the call was successful, or 0 if the call failed.

Discussion

This function returns pointers inside the original data pointer - do NOT call AIL_mem_free_lock on these pointers. If you want to obtain copies of the XMIDI and DLS chunks inside the original file image, you can use the AIL_extract_DLS function.

This function does not decompress the DLS data in the merged XMIDI file - if you need to decompress the data, use AIL_extract_DLS.

A good way to decide whether to use AIL_extract_DLS or AIL_find_DLS is whether the DLS data is compressed. If the data is uncompressed, then you can pass it directly to AIL_DLS_load_memory, so AIL_find_DLS can be used. If the data is compressed, then you must decompress it with AIL_extract_DLS before handing it off to AIL_DLS_load_memory. You can determine whether the data is compressed or not with the AIL_file_type function.

Group: Utility Services
Related Functions: AIL_DLS_load_file, AIL_DLS_load_memory, AIL_compress_DLS, AIL_extract_DLS, AIL_file_type, AIL_filter_DLS_with_XMI, AIL_find_DLS, AIL_mem_free_lock, AIL_merge_DLS_with_XMI
Related Basic Types: S32, U32, void *, void const *


AIL_merge_DLS_with_XMI

The function AIL_merge_DLS_with_XMI merges an XMIDI file and a DLS or MLS file together.

S32 AIL_merge_DLS_with_XMI(
  void const * XMI,
  void const * dls,
  void * *mss,
  U32 *msssize
);

In Parameters

XMI
should point to a loaded XMIDI file image.
dls
should point to a loaded DLS or MLS file image.

Out Parameters

mss
should be the address of a " void* " pointer that will return with the pointer to the new merged XMIDI file image. This parameter can be NULL if you don't need it.
msssize
should be the address of an unsigned 32-bit integer that will return with the size of the new merged XMIDI file image. This parameter can be NULL if you don't need it.

Returns

1, if the call was successful, or 0 if the call failed.

Discussion

You must free the pointer returned in mss with AIL_mem_free_lock.

You extract the XMIDI and DLS chunks with the AIL_extract_DLS function.

You find the XMIDI and DLS chunks with the AIL_find_DLS function.

XMIDI files with merged DLS data usually have an ".MSS" extension.

Group: Utility Services
Related Functions: AIL_compress_DLS, AIL_extract_DLS, AIL_find_DLS, AIL_mem_free_lock
Related Basic Types: S32, U32, void *, void const *


AIL_filter_DLS_with_XMI

The function AIL_filter_DLS_with_XMI filters out unused instruments in a DLS file given one or more XMIDI files.

S32 AIL_filter_DLS_with_XMI(
  void const * XMI,
  void const * dls,
  void * *filtereddls,
  U32 *dlssize,
  S32 flags,
  AILLENGTHYCB callback
);

In Parameters

XMI
should point to a loaded XMIDI file image.
dls
should point to a loaded DLS or MLS file image.
flags
is zero, or one or more of the MILES_FILTER_DLS_FLAGS.
callback
should be set to the address of the callback function which is invoked at several stages of the filtering process. See AILLENGTHYCB for a description of this callback.

Out Parameters

filtereddls
should be the address of a " void* " pointer that will return with the pointer to the new filtered DLS file image. This parameter can be NULL if you don't need it.
dlssize
should be the address of an unsigned 32-bit integer that will return with the size of the new filtered DLS file image. This parameter can be NULL if you don't need it.

Returns

1, if the call was successful, or 0 if the call failed.

Discussion

You must free the pointer returned in filtereddls with AIL_mem_free_lock.

Depending on the complexity of the XMIDI and DLS files, this function can take several minutes to return.

Group: Utility Services
Related Functions: AILLENGTHYCB, AIL_extract_DLS, AIL_find_DLS, AIL_mem_free_lock
Related Basic Types: MILES_FILTER_DLS_FLAGS, S32, U32, void *, void const *


MILES_FILTER_DLS_FLAGS

The basic type MILES_FILTER_DLS_FLAGS specifies options to use when filtering DLS instrument sets with an XMIDI file.

Fundamental Values

Value | Description
AILFILTERDLS_USINGLIST | This flag means that the XMI parameter doesn't point to XMIDI file, rather it points to a table of unsigned 32-bit integers with the following structure: 1st U32 - number of XMIDI files to filter with. 2nd U32 - pointer to the first XMIDI file image. 3rd U32 - pointer to the second XMIDI file image. 4th U32 - pointer to the third XMIDI file image. ... etc. By using this flag, you can create an 'application-wide' DLS file - that is, a single DLS file that can play any XMIDI file in your application.

Group: Utility Services
Related Functions: AIL_filter_DLS_with_XMI


AIL_list_MIDI

The function AIL_list_MIDI creates a detailed listing of a MIDI file.

S32 AIL_list_MIDI(
  void const * MIDI,
  U32 MIDI_size,
  char * *list,
  U32 *listsize,
  S32 flags
);

In Parameters

MIDI
points to a file image containing standard MIDI data.
MIDI_size
is the length of the MIDI data.
flags
is zero, or one or more of the MILES_LIST_MIDI_FLAGS.

Out Parameters

list
should be the address of a " void* " pointer that will return with the pointer to the new ASCII MIDI list. This parameter can be NULL if you don't need it.
listsize
should be the address of an unsigned 32-bit integer that will return with the size of the new ASCII MIDI list. This parameter can be NULL if you don't need it.

Returns

1, if the call was successful, or 0 if the call failed.

Discussion

You must free the pointer returned in list with AIL_mem_free_lock.

The output ASCII list is zero-terminated.

This function is supported under Windows only.

Group: Utility Services
Related Functions: AIL_list_DLS, AIL_mem_free_lock
Related Basic Types: MILES_LIST_MIDI_FLAGS, S32, U32, char *, void const *


MILES_LIST_MIDI_FLAGS

The basic type MILES_LIST_MIDI_FLAGS specifies flags to use when listing a MIDI file.

Fundamental Values

Value | Description
AILMIDILIST_ROLANDSYSEX | Display the System Exclusive messages in Roland format.
AILMIDILIST_ROLANDUN | Display an unabridged version of the Roland Programmer's Reference in the MIDI Listing (note that this will create a huge listing).
AILMIDILIST_ROLANDAB | Display an abridged version of the Roland Programmer's Reference in the MIDI Listing (note that this will create a larger listing).

Group: Utility Services
Related Functions: AIL_list_MIDI


AIL_list_DLS

The function AIL_list_DLS creates a detailed listing of a DLS or MLS file.

S32 AIL_list_DLS(
  void const * dls,
  char * *list,
  U32 *listsize,
  S32 flags,
  char const * filename
);

In Parameters

dls
points to a file image containing the DLS or MLS file.
flags
is zero, or one or more of the MILES_LIST_DLS_FLAGS.
filename
is the name of the DLS file. The filename is used for insertion in the list file title as well as for directory creation if the AILDLSLIST_DUMP_WAVE flag is used.

Out Parameters

list
should be the address of a " void* " pointer that will return with the pointer to the new ASCII DLS list. This parameter can be NULL if you don't need it.
listsize
should be the address of an unsigned 32-bit integer that will return with the size of the new ASCII DLS list. This parameter can be NULL if you don't need it.

Returns

1, if the call was successful, or 0 if the call failed.

Discussion

You must free the pointer returned in list with AIL_mem_free_lock.

The output ASCII list is zero-terminated.

This function is supported under Windows only.

Group: Utility Services
Related Functions: AIL_list_MIDI, AIL_mem_free_lock
Related Basic Types: MILES_LIST_DLS_FLAGS, S32, U32, char *, char const *, void const *


MILES_LIST_DLS_FLAGS

The basic type MILES_LIST_DLS_FLAGS specifies flags to use when listing a DLS file.

Fundamental Values

Value | Description
AILDLSLIST_ARTICULATION | Display DLS articulation data (makes the listing much larger).
AILDLSLIST_DUMP_WAVS | This flag causes each of the individual wave files inside the DLS file to be dumped into a subdirectory off the current directory named "filename Samples".

Group: Utility Services
Related Functions: AIL_list_DLS


AIL_inspect_MP3

The function AIL_inspect_MP3 obtains some basic information about the structure of an MPEG-1 Layer 3 audio file, and prepares for optional header enumeration.

void AIL_inspect_MP3(
  MP3_INFO *inspection_state,
  U8 * MP3_file_image,
  S32 MP3_image_size
);

In Parameters

MP3_file_image
points to an MP3 file image owned by the application.
MP3_image_size
The size, in bytes, of the MP3 file image.

Out Parameters

inspection_state
points to an instance of an MP3_INFO structure owned by the application.

Discussion

This function can locate ID3v1 and ID3v2 tags at the end and beginning of an MP3 file image, respectively. It also prepares an MP3_INFO structure instance for use with AIL_enumerate_MP3_frames.

See the MP3_INFO structure description for details about the information retrieved by this function.

Group: Utility Services
Related Functions: AIL_enumerate_MP3_frames
Related Basic Types: S32, U8, void
Related Structures: MP3_INFO


AIL_enumerate_MP3_frames

The function AIL_enumerate_MP3_frames obtains information about successive frames from an MPEG-1 Layer 3 audio file.

S32 AIL_enumerate_MP3_frames(
  MP3_INFO *inspection_state
);

Out Parameters

inspection_state
points to an instance of an MP3_INFO structure owned by the application and previously initialized by a call to AIL_inspect_MP3.

Returns

1 if the frame-data portion of the MP3_INFO structure represents a valid frame; 0 if no (further) valid frames exist in the file image.

Discussion

This function returns information about all of the valid MP3 frames in the file image, beginning with the first, by filling in the appropriate MP3_INFO structure fields.

You can inspect all of the frames in an MP3 file image with the following code:

   MP3_INFO info;
   AIL_inspect_MP3(&info,
                   my_MP3_file_image,
                   size_in_bytes_of_my_MP3_file_image);
   printf("Valid MP3 data, if any, begins at %X\n",info.start_MP3_data);
   while (AIL_enumerate_MP3_frames(&info))
      {
      printf("Valid frame found at byte offset %d from info.start_MP3_data\n",info.byte_offset);
      }

ID3v2 tags appearing in the middle of the file will not be reported by this function; they will be skipped. An ID3v2 tag at the beginning of the file, if any, will be logged by the initial call to AIL_inspect_MP3.

See the MP3_INFO structure description for details about the information retrieved by this function.

Group: Utility Services
Related Functions: AIL_inspect_MP3
Related Basic Types: S32
Related Structures: MP3_INFO


MP3_INFO

struct MP3_INFO
{
  U8 * MP3_file_image;
  S32 MP3_image_size;
  U8 * ID3v2;
  S32 ID3v2_size;
  U8 * ID3v1;
  U8 * start_MP3_data;
  U8 * end_MP3_data;
  S32 sample_rate;
  S32 bit_rate;
  S32 channels_per_sample;
  S32 samples_per_frame;
  S32 byte_offset;
  S32 next_frame_expected;
  S32 average_frame_size;
  S32 data_size;
  S32 header_size;
  S32 side_info_size;
  S32 ngr;
  S32 main_data_begin;
  S32 hpos;
  S32 MPEG1;
  S32 MPEG25;
  S32 layer;
  S32 protection_bit;
  S32 bitrate_index;
  S32 sampling_frequency;
  S32 padding_bit;
  S32 private_bit;
  S32 mode;
  S32 mode_extension;
  S32 copyright;
  S32 original;
  S32 emphasis;
};

In Members

MP3_file_image
Original MP3_file_image pointer passed to AIL_inspect_MP3.
MP3_image_size
Original MP3_image_size passed to AIL_inspect_MP3.
ID3v2
ID3v2 tag, if not NULL.
ID3v2_size
Size of tag in bytes.
ID3v1
ID3v1 tag, if not NULL (always 128 bytes long if present).
start_MP3_data
Pointer to start of data area in file (not necessarily first valid frame).
end_MP3_data
Pointer to last valid byte in MP3 data area (before ID3v1 tag, if any).
sample_rate
Sample rate in Hz (normally constant across all frames in file).
bit_rate
Bits/second for current frame.
channels_per_sample
Always 1 or 2.
samples_per_frame
Always 576 or 1152 samples in each MP3 frame, depending on rate.
byte_offset
Offset of frame from start_MP3_data (i.e., suitable for use as loop point).
next_frame_expected
Offset from start_MP3_data where the next frame was expected. Will normally be equal to byte_offset unless garbage data or an ID3v2 tag was skipped before the currently-enumerated frame, or EOF was reached before the next frame header.
average_frame_size
Average source bytes per frame, determined solely by bit rate and sample rate.
data_size
# of data-only bytes in this particular frame.
header_size
4 or 6 bytes, depending on CRC.
side_info_size
Valid for layer 3 side info only.
ngr
Always 2 for MPEG1, else 1.
main_data_begin
Always 0 in files with no bit reservoir.
hpos
Current bit position in header/side buffer.
MPEG1
Data copied directly from frame header; see ISO docs for info.
MPEG25
Data copied directly from frame header; see ISO docs for info.
layer
Data copied directly from frame header; see ISO docs for info.
protection_bit
Data copied directly from frame header; see ISO docs for info.
bitrate_index
Data copied directly from frame header; see ISO docs for info.
sampling_frequency
Data copied directly from frame header; see ISO docs for info.
padding_bit
Data copied directly from frame header; see ISO docs for info.
private_bit
Data copied directly from frame header; see ISO docs for info.
mode
Data copied directly from frame header; see ISO docs for info.
mode_extension
Data copied directly from frame header; see ISO docs for info.
copyright
Data copied directly from frame header; see ISO docs for info.
original
Data copied directly from frame header; see ISO docs for info.
emphasis
Data copied directly from frame header; see ISO docs for info.

Discussion

All MP3_INFO fields other than those documented above are for internal use, and may change between MSS versions.

Fields between MP3_file_image and end_MP3_data, inclusive, are valid as soon as AIL_inspect_MP3 returns, even if the file contains no valid MP3 frames.

All remaining fields pertain to the current frame being inspected, and are valid only after AIL_enumerate_MP3_frames has returned TRUE.

Group: Utility Services
Related Functions: AIL_enumerate_MP3_frames, AIL_inspect_MP3
Related Basic Types: S32, U8


Low-Level Sony PlayStation 2 Support Services

Discussion

The Low-Level Sony PlayStation 2 Support Services can be used by the application to access the IOP coprocessor and/or change how MSS uses the PS2 hardware resources.

Low-Level Sony PlayStation 2 Support Services
AIL_set_scratchpad_policy | specifies whether (and how) MSS can use the PS2's scratchpad RAM.
AIL_scratchpad_policy | returns the current MSS scratchpad-usage policy.
MSS_RESOURCE_POLICY | specifies a usage policy for the AIL_set_scratchpad_policy function.


AIL_set_scratchpad_policy

The function AIL_set_scratchpad_policy specifies whether (and how) MSS can use the PS2's scratchpad RAM.

MSS_RESOURCE_POLICY AIL_set_scratchpad_policy(
  MSS_RESOURCE_POLICY policy
);

In Parameters

policy
specifies the requested resource-usage policy.

Returns

The resource policy currently applicable to scratchpad RAM usage.

Discussion

By default, MSS does not use the PS2 scratchpad. However, certain operations (currently limited to MP3 decoding and DTS encoding) can be accelerated slightly by giving MSS permission to store intermediate results in SPRAM.

If your application does not use MP3 decoding or DTS output, then you do not need to call this function. If your application uses Miles's DTS or MP3 support but otherwise does not use the scratchpad RAM for anything including mixed foreground and background calls to the MP3 decoder, you can call this function with MSS_USE_WITHOUT_SAVING. If you need to be able to use the scratchpad with interrupts enabled, but would like the interrupt-driven parts of MSS to use it as well, you should pass MSS_USE_AND_SAVE to this function. (Saving and restoring the scratchpad contents imposes a performance cost of its own, so we can run a little faster if we don't have to preserve the scratchpad contents at interrupt time.)

You can call this function at any time. However, any requested changes made to Miles's scratchpad-usage policy will not take effect until the next end-of-buffer interrupt that Miles receives from the IOP. At that time, the value reported by AIL_scratchpad_policy (as well as this function) will change to reflect the new policy. Note that any foreground calls made by the application that end up calling the MP3 decoder to decompress audio data will not save the scratchpad contents under any conditions. This means that if you need to disable scratchpad usage in preparation for a foreground call to AIL_process_digital_audio or a similar function, you'll want to poll AIL_scratchpad_policy first until your requested change takes effect.

Group: Low-Level Sony PlayStation 2 Support Services
Related Sections: Miles DTS Provider for the Sony PS2, Resource Usage on the Playstation 2
Related Functions: AIL_process_digital_audio, AIL_scratchpad_policy
Related Basic Types: MSS_RESOURCE_POLICY


AIL_scratchpad_policy

The function AIL_scratchpad_policy returns the current MSS scratchpad-usage policy.

MSS_RESOURCE_POLICY AIL_scratchpad_policy(
  void
);

In Parameters

Returns

The resource policy currently applicable to scratchpad RAM usage.

Discussion

By default, MSS does not use the PS2 scratchpad. However, certain operations (currently limited to MP3 decoding and DTS encoding) can be accelerated slightly by giving MSS permission to store intermediate results in SPRAM. See AIL_set_scratchpad_policy for a detailed discussion.

You can call AIL_set_scratchpad_policy and AIL_scratchpad_policy at any time. However, any requested changes made to Miles's scratchpad-usage policy will not take effect until the next end-of-buffer interrupt that Miles receives from the IOP. At that time, the value reported by AIL_scratchpad_policy will change to reflect the new policy. Note that any foreground calls made by the application that end up calling the MP3 decoder to decompress audio data will not save the scratchpad contents under any conditions. This means that if you need to disable scratchpad usage in preparation for a foreground call to AIL_process_digital_audio or a similar function, you'll want to poll AIL_scratchpad_policy first until your requested change takes effect.

Group: Low-Level Sony PlayStation 2 Support Services
Related Functions: AIL_process_digital_audio, AIL_scratchpad_policy, AIL_set_scratchpad_policy
Related Basic Types: MSS_RESOURCE_POLICY, void


MSS_RESOURCE_POLICY

The basic type MSS_RESOURCE_POLICY specifies a usage policy for the AIL_set_scratchpad_policy function.

Fundamental Values

Value | Description
MSS_DO_NOT_USE | MSS will not use the PS2 scratchpad RAM under any conditions. This is the default scratchpad policy.
MSS_USE_AND_SAVE | MSS will use the PS2 scratchpad for certain tasks, and will save and restore its contents at interrupt time to avoid conflicts with any other users of the scratchpad.
MSS_USE_WITHOUT_SAVING | MSS will use the PS2 scratchpad for certain tasks, and will NOT preserve its contents at interrupt time. This policy should be selected only if your application (and any of its other libraries) will not make use of the scratchpad.
MSS_USED | Reserved for internal use.

Discussion

By default, MSS does not use the PS2 scratchpad. However, certain operations (currently limited to MP3 decoding and DTS encoding) can be accelerated slightly by giving MSS permission to store intermediate results in SPRAM.

If your application does not require MP3 or DTS support, then you do not need to change the scratchpad-usage policy. If your application uses Miles's MP3 or DTS support but otherwise does not use the scratchpad RAM for anything including mixed foreground and background calls to the MP3 decoder, you can call this function with MSS_USE_WITHOUT_SAVING. If you need to be able to use the scratchpad with interrupts enabled, but would like the interrupt-driven parts of MSS to use it as well, you should pass MSS_USE_AND_SAVE to this function. (Saving and restoring the scratchpad contents imposes a performance cost of its own, so we can run a little faster if we don't have to preserve the scratchpad contents at interrupt time.)

You can change the scratchpad-usage policy at any time. However, any requested changes made to Miles's scratchpad-usage policy will not take effect until the next end-of-buffer interrupt that Miles receives from the IOP. At that time, the value reported by AIL_scratchpad_policy will change to reflect the new policy. Note that any foreground calls made by the application that end up calling the MP3 decoder to decompress audio data will not save the scratchpad contents under any conditions. This means that if you need to disable scratchpad usage in preparation for a foreground call to AIL_process_digital_audio or a similar function, you'll want to poll AIL_scratchpad_policy first until your requested change takes effect.

Group: Low-Level Sony PlayStation 2 Support Services
Related Functions: AIL_process_digital_audio, AIL_scratchpad_policy, AIL_set_scratchpad_policy


The RAD_IOP API for the Sony PS2

Discussion

There are several chips in the Sony PS2. The EE is the primary chip that your game (and the RAD SDKs) run on. There is also the IOP which is in charge of I/O and sound control. The RAD_IOP API provides a high-level interface from the EE to control the IOP.

The RAD IOP layer is designed to do four things:

1) Asynchronous file I/O on the EE. You can request async file reads to execute in the background, and RAD_IOP will tell the IOP to go off and do them for you. The destination of these reads can be a memory location on the EE, the IOP, or the SPU. You can one flag, and the data goes somewhere else automatically. You can then get a callback, or just check a status field to determine when the read completes. This is the API that the RAD SDKs use to do it's file I/O, but you can use it for your own I/O too.

2) PCM sound streaming. You can request that RAD_IOP start a streaming buffer, and it will call you back on an interrupt to fill the buffer. You simply copy your sound into the buffer in each interrupt. This is the API that the RAD SDKs use to play sound, but like the I/O API, you can use it to play your own sound as well.

3) Drift-free timer services. You can request that RAD_IOP start calling a function callback at a certain timer frequency. They are drift-free in the sense that we monitor how long between each callback and will call you less and more often to maintain the exact callback frequency you requested.

4) Play ADPCM audio on the Sony PS2 audio hardware (see the next section).

The RAD_IOP layer was designed to run along side any other EE or IOP modules, so you can let the RAD SDKs use this API by itself, or your game can use it and save you a little work.

The next sections describe the functions in this handy API.

The RAD_IOP API for the Sony PS2
RAD_IOPStartUp | opens the RAD_IOP API for use.
SOUND_CORE_FLAGS | Specifies the sound flags that RAD_IOP should use.
RAD_IOPMemoryAmount | returns the amount of IOP memory in bytes that RAD_IOP will need.
RAD_IOPShutDown | closes the RAD_IOP library.
RAD_IOPQueueAsyncOpenFile | asynchronously opens a file handle.
RAD_IOP_ASYNC_OPEN_DATA | is a structure used with the RAD_IOPQueueAsyncOpenFile function.
RAD_IOP_STATUS_VALUES | Specifies the status values for the RAD_IOP asynchronous I/O functions.
RAD_IOP_OPENCALLBACK | points to a function that will be called when the async open file completes.
RAD_IOPGetFileHandleToIOPMemory | creates a file handle that can be used to read from IOP memory.
RAD_IOPGetFileHandleToSPUMemory | creates a file handle that can be used to read from SPU memory.
RAD_IOPGetFileHandleToLSN | creates a file handle that directly address a Logical Sector Number on a CD or DVD.
RAD_IOPQueueAsyncReadAtTop | queues an asynchronous read to be performed in the background at the highest priority.
RAD_IOP_ASYNC_READ_DATA | is a structure used to perform an asynchronous read.
RAD_IOP_ADDRESS_VALUES | Specifies the type of memory that you want to read into for the RAD_IOP asynchronous I/O functions.
RAD_IOP_READCALLBACK | points to a function that will be called when the async read completes.
RAD_IOPQueueAsyncReadAtBottom | queues an asynchronous read to be performed in the background at the lowest priority.
RAD_IOPGetIOStatus | returns the error code from a failed IO request.
RAD_IOPCancelAsyncOpen | cancels a previous asynchronous file open.
RAD_IOPCancelAsyncRead | cancels a previous asynchronous file read.
RAD_IOPCancelFileAsyncs | cancels all previous asynchronous file reads for a specified file handle.
RAD_IOPCancelGroupOfAsyncs | cancels all previous asynchronous file opens and reads for a specified group id.
RAD_IOPCancelAllAsyncs | cancels all previous asynchronous file opens and reads.
RAD_IOPCloseFile | closes a file handle opened with RAD_IOPQueueAsyncOpenFile.
RAD_IOPRegisterSoundCallback | registers a sound data structure to call your sound interrupt callback.
RAD_IOP_SOUND_DATA | is a structure used to control a sound interrupt callback.
RAD_IOP_SOUNDCALLBACK | points to a function that will be called periodically to fill a streaming sound buffer.
RAD_IOPStartSound | starts calling a previously registered sound callback.
RAD_IOPPauseSound | pauses a previously registered sound callback.
RAD_IOPUnregisterSoundCallback | unregisters a sound callback.
RAD_IOPRegisterTimerCallback | registers a timer structure to call your timer interrupt callback at a certain frequency.
RAD_IOP_TIMER_DATA | is a structure used to call a timer interrupt callback.
RAD_IOP_TIMERCALLBACK | points to a function that will be called periodically.
RAD_IOPStartTimer | starts calling a previously registered timer callback.
RAD_IOPPauseTimer | pauses a previously registered timer callback.
RAD_IOPUnregisterTimerCallback | unregisters a timer callback.
RAD_IOPHardwareVolumes | sets the sound core hardware volumes.
RADTimerRead | returns a rolling millisecond timer.


RAD_IOPStartUp

The function RAD_IOPStartUp opens the RAD_IOP API for use.

S32 RAD_IOPStartUp(
  U32 num_file_buffers,
  S32 command_handler_index,
  VOID_PTR IOP_memory,
  SOUND_CORE_FLAGS sound_flags
);

In Parameters

num_file_buffers
Specifies the number of file buffers to use. This should be the maximum files that you expect to be reading from at once. Each file buffer is 4096 bytes of EE memory.
command_handler_index
Specifies the index of the command handler to use. If you don't currently use command handlers, use -1 for the flag and we will set one up.
IOP_memory
Specifies an IOP address that is used for IOP side buffering. Use the RAD_IOPMemoryAmount function to query how large this buffer should be. You will usually use the sceSifAllocIopHeap function to allocate this memory.
sound_flags
Specifies the sound core to use.

Returns

Returns non-zero for success, and zero for failure.

Discussion

This function starts up the RAD IOP API layer. It also starts up an internal IOP IRX to receive the calls you make. The RAD IOP layer is designed to do three things:

1) Asynchronous file I/O on the EE. You can request async file reads to execute in the background, and RAD_IOP will tell the IOP to go off and do them for you. You can then get a callback, or just check a status field to determine when the read completes. This is the API that we use to do its file I/O, but you can use it for your own I/O too.

2) PCM sound streaming. You can request that RAD_IOP start a streaming buffer, and it will call you back on an interrupt to fill the buffer. You simply copy your sound into the buffer in each interrupt. This is the API that we use to play sound, but like the I/O API, you can use it to play your own sound as well.

3) Drift-free timer services. You can request that RAD_IOP start calling a function callback at a certain timer frequency. They are drift-free in the sense that we monitor how long between each callback and will call you less and more often to maintain the exact callback frequency you requested.

You can use these features with or without Bink or Miles, and you can use all of these features, or just some of them.

Normally, when using this API just for Bink or Miles, you will simply call it with one file buffer, and one sound core flag, and then tell us which core you requested.

You can call this startup routine multiple times, but only the first call configures the library. You need to call RAD_IOPShutDown a matching number of times to shut the library down.

Group: The RAD_IOP API for the Sony PS2
Related Sections: Miles DTS Provider for the Sony PS2
Related Functions: RAD_IOPMemoryAmount, RAD_IOPShutDown
Related Basic Types: S32, SOUND_CORE_FLAGS, U32, VOID_PTR
Related Structures: RAD_IOP_SOUND_DATA


SOUND_CORE_FLAGS

The basic type SOUND_CORE_FLAGS Specifies the sound flags that RAD_IOP should use.

Fundamental Values

Value | Description
RAD_IOP_NEED_CORE0 | Tells RAD_IOP that you want to use the PCM channel on core 0.
RAD_IOP_NEED_CORE1 | Tells RAD_IOP that you want to use the PCM channel on core 1.
RAD_IOP_SPDIF | Tells RAD_IOP to route raw bitstream audio data (as opposed to PCM values) to the S/PDIF port.
RAD_IOP_NO_INIT_LIBSD | Tells RAD_IOP not to initialize libsb on the IOP (because you have already done it).

Discussion

These flags are used with RAD_IOPStartUp and RAD_IOPMemoryAmount to specify the sound resources that you want to use. We need only one PCM sound channel, but you can request both of them if you want to use the other one directly. The RAD_IOP also allows for the outgoing sound to be mixed together, so you don't really need both sound cores, even if you are playing audio outside of Bink or Miles at the same time.

The PS2's S/PDIF port is always active, unless explicitly turned off by the sceSdSetCoreAttr function. Normally, the S/PDIF port provides a stereo 48-kHz 16-bit PCM "copy" of the audio output at the line-out jacks. When you specify the RAD_IOP_SPDIF flag, however, the audio data returned by the EE in response to a sound callback is treated as a raw bitstream rather than PCM data. It is transmitted through the S/PDIF port at 1.536 Mbit/s for the benefit of a DTS- or Dolby Digital-equipped receiver. Consequently, the Miles Sound System's DTS encoder requires the RAD_IOP_SPDIF flag to be specified at startup time. (It must always be OR'ed with the RAD_IOP_NEED_CORE0 flag, since core-0 functionality is required for bitstream transmission.)

Group: The RAD_IOP API for the Sony PS2
Related Functions: RAD_IOPMemoryAmount, RAD_IOPStartUp


RAD_IOPMemoryAmount

The function RAD_IOPMemoryAmount returns the amount of IOP memory in bytes that RAD_IOP will need.

U32 RAD_IOPMemoryAmount(
  SOUND_CORE_FLAGS sound_flags
);

In Parameters

sound_flags
Specifies the sound flags that you are going to use in the RAD_IOPStartUp call.

Returns

Returns the amount of IOP memory that you need to allocate.

Discussion

This function tells you how much IOP memory RAD_IOP needs for your flags. You then usually call sceSifAllocIopHeap to allocate this memory and then pass that address to RAD_IOPStartUp. You shouldn't free this memory until you have called RAD_IOPShutDown.

Group: The RAD_IOP API for the Sony PS2
Related Sections: Miles DTS Provider for the Sony PS2
Related Functions: RAD_IOPMemoryAmount, RAD_IOPShutDown, RAD_IOPStartUp
Related Basic Types: SOUND_CORE_FLAGS, U32


RAD_IOPShutDown

The function RAD_IOPShutDown closes the RAD_IOP library.

S32 RAD_IOPShutDown();

Returns

Non-zero if the library was closed, zero if it is still open (because RAD_IOPShutDown has not been called the same number of times that RAD_IOPStartUp has been).

Discussion

This function closes the RAD_IOP library down. It cancels any I/Os that were in progress and then exits the and IOP IRX that we started. You can then free the IOP memory that you previously passed in RAD_IOPStartUp.

Group: The RAD_IOP API for the Sony PS2
Related Functions: RAD_IOPMemoryAmount, RAD_IOPShutDown, RAD_IOPStartUp
Related Basic Types: S32


RAD_IOPQueueAsyncOpenFile

The function RAD_IOPQueueAsyncOpenFile asynchronously opens a file handle.

S32 RAD_IOPQueueAsyncOpenFile(
  RAD_IOP_ASYNC_OPEN_DATA *open_data
);

Out Parameters

open_data
Specifies the input and output parameters for the open.

Returns

Non-zero if the open was queued successfully, zero for failure.

Discussion

This function queues up a file open to happen in the background. You fill out the name field, and optionally the group and callback fields, and then call this function.

The name field can be any normal PS2 formatted name ("cdrom0:\\MOVIES\\CREDITS.BIK;1" or "host:c:\\movies\\credits.bik").

You can check for completion using the callback, or just poll on the status field. If the status is set to RAD_IOP_STATUS_DONE, then the file_handle and size fields have been set correctly.

You should call RAD_IOPCloseFile to close any file handles opened with this function.

A file handle value can be one of four types:
1) A file on the host or the external hard drive, which is just the value returned from the IOP C runtime open function,
2) For CD or DVD files, it is basically the starting sector number (encoded with RAD_IOPGetFileHandleToLSN),
3) A pointer to IOP memory (encoded with RAD_IOPGetFileHandleToIOPMemory) - used to get data from IOP RAM,
4) A pointer to SPU memory (encoded with RAD_IOPGetFileHandleToSPUMemory) - used to get data from SPU RAM.

This function is required to get the first type of file handle, and it can also return the second type, by looking for the starting sector of a filename on the CD or DVD. But, if you already know the logical sector number of the file, RAD_IOPGetFileHandleToLSN is faster.

The open_data structure should remain valid until the operation is finished. That is, don't free the memory until the status is greater than or equal to RAD_IOP_STATUS_DONE.

Group: The RAD_IOP API for the Sony PS2
Related Functions: RAD_IOPCloseFile, RAD_IOPGetFileHandleToIOPMemory, RAD_IOPGetFileHandleToLSN, RAD_IOPGetFileHandleToSPUMemory, RAD_IOPQueueAsyncReadAtBottom, RAD_IOPQueueAsyncReadAtTop
Related Basic Types: RAD_IOP_STATUS_VALUES, S32
Related Structures: RAD_IOP_ASYNC_OPEN_DATA, RAD_IOP_ASYNC_READ_DATA


RAD_IOP_ASYNC_OPEN_DATA

The structure RAD_IOP_ASYNC_OPEN_DATA is a structure used with the RAD_IOPQueueAsyncOpenFile function.

struct RAD_IOP_ASYNC_OPEN_DATA
{
  CHAR_PTR name;
  RAD_IOP_OPENCALLBACK callback;
  U32 group;
  RAD_IOP_STATUS_VALUES status;
  S32 file_handle;
  U32 size;
};

In Members

name
Specifies the file name to open. This should be preceded with "cdrom0:", "host0:", or "hdd0:". For CD or DVD files, the filename should also end with a ";1".
callback
Specifies a callback that should be made upon completion. If you don't want to be called back, then set this field to zero.
group
Optional. Specifies the group identifier of this open. The group id allows you to cancel I/Os for an entire group of requests, if necessary.

Out Members

status
Contains the current status of the async open.
file_handle
Returns the open file handle, if status returns RAD_IOP_STATUS_DONE.
size
Returns the size of the open file.

Discussion

This structure is both the input and the output of the RAD_IOPQueueAsyncOpenFile function. You fill out the in parameters, and the RAD_IOP returns the out parameters.

If you don't have a callback set, then you can spin on the status field and wait for it to go greater than or equal to RAD_IOP_STATUS_COMPLETE. You then query the status for RAD_IOP_STATUS_DONE to determine if the open succeeded.

Group: The RAD_IOP API for the Sony PS2
Related Functions: RAD_IOPQueueAsyncOpenFile, RAD_IOP_OPENCALLBACK
Related Basic Types: CHAR_PTR, RAD_IOP_STATUS_VALUES, S32, U32


RAD_IOP_STATUS_VALUES

The basic type RAD_IOP_STATUS_VALUES Specifies the status values for the RAD_IOP asynchronous I/O functions.

Fundamental Values

Value | Description
RAD_IOP_STATUS_NONE | Status has not been set yet.
RAD_IOP_STATUS_QUEUED | The request is queued to be processed in the background.
RAD_IOP_STATUS_RUNNING | The request is currently being processed in the background.
RAD_IOP_STATUS_COMPLETE | Any status greater than or equal to RAD_IOP_STATUS_COMPLETE means that the background operation is completed.
RAD_IOP_STATUS_CANCELLED | One of the asynchronous I/O cancel functions was called on this request.
RAD_IOP_STATUS_ERROR | The background operation failed (file not found on open, or I/O error on read).
RAD_IOP_STATUS_DONE | The background operation was successfully completed.

Discussion

These flags are used with the RAD_IOP async open and read functions. They give you the current status of the background operation.

Group: The RAD_IOP API for the Sony PS2
Related Functions: RAD_IOPGetIOStatus, RAD_IOPQueueAsyncOpenFile, RAD_IOPQueueAsyncReadAtBottom, RAD_IOPQueueAsyncReadAtTop, RAD_IOPQueueAsyncSPUGlobalState, RAD_IOPQueueAsyncSPUVoiceState
Related Structures: RAD_IOP_ASYNC_OPEN_DATA, RAD_IOP_ASYNC_READ_DATA, RAD_IOP_SOUND_DATA, RAD_IOP_SPU_GLOBAL_STATE, RAD_IOP_SPU_VOICE_STATE, RAD_IOP_TIMER_DATA


RAD_IOP_OPENCALLBACK

The function RAD_IOP_OPENCALLBACK points to a function that will be called when the async open file completes.

void RAD_IOP_OPENCALLBACK(
  RAD_IOP_ASYNC_OPEN_DATA const *open_data
);

In Parameters

open_data
Specifies the pointer to the structure that you called RAD_IOPQueueAsyncOpenFile with.

Discussion

This function will be called once the open is completed (at interrupt level). Be careful that the code you write in this function is interrupt safe.

This file handle can be used with the BinkOpen function to play a Bink movie out of IOP RAM, or with the AIL_open_stream function to play a sound file out of IOP RAM.

This callback will be made for success or failure, so check the status field value to determine whether the open actually succeeded.

Group: The RAD_IOP API for the Sony PS2
Related Basic Types: void
Related Structures: RAD_IOP_ASYNC_OPEN_DATA


RAD_IOPGetFileHandleToIOPMemory

The function RAD_IOPGetFileHandleToIOPMemory creates a file handle that can be used to read from IOP memory.

U32 RAD_IOPGetFileHandleToIOPMemory(
  VOID_PTR IOP_address
);

In Parameters

IOP_address
Specifies the address in IOP memory that you want to start reading from.

Returns

File handle to the IOP memory.

Discussion

This function creates a file handle that can be used to read asynchronously from IOP memory.

You can copy data from the IOP to the SPU by using these kinds of file handles and then using the async read function with the appropriate destination pointer type.

You don't have to close this type of file handle.

Group: The RAD_IOP API for the Sony PS2
Related Functions: AIL_open_stream, RAD_IOPQueueAsyncOpenFile, RAD_IOPQueueAsyncReadAtBottom, RAD_IOPQueueAsyncReadAtTop
Related Basic Types: U32, VOID_PTR


RAD_IOPGetFileHandleToSPUMemory

The function RAD_IOPGetFileHandleToSPUMemory creates a file handle that can be used to read from SPU memory.

U32 RAD_IOPGetFileHandleToSPUMemory(
  VOID_PTR IOP_address
);

In Parameters

IOP_address
Specifies the address in SPU memory that you want to start reading from.

Returns

File handle to the SPU memory.

Discussion

This function creates a file handle that can be used to read asynchronously from SPU memory.

This file handle can be used with the BinkOpen function to play a Bink movie out of SPU RAM, or with the AIL_open_stream function to play a sound file out of SPU RAM.

You can copy data from the SPU to the IOP by using these kinds of file handles and then using the async read function with the appropriate destination pointer type.

You don't have to close this type of file handle.

Group: The RAD_IOP API for the Sony PS2
Related Functions: RAD_IOPQueueAsyncOpenFile, RAD_IOPQueueAsyncReadAtBottom, RAD_IOPQueueAsyncReadAtTop
Related Basic Types: U32, VOID_PTR


RAD_IOPGetFileHandleToLSN

The function RAD_IOPGetFileHandleToLSN creates a file handle that directly address a Logical Sector Number on a CD or DVD.

U32 RAD_IOPGetFileHandleToLSN(
  U32 LSN
);

In Parameters

LSN
Specifies the logical sector number on the CD or DVD.

Returns

File handle to the SPU memory.

Discussion

This function creates a file handle that can be used to read asynchronously from a specific sector off a CD or DVD.

You don't have to close this type of file handle.

Group: The RAD_IOP API for the Sony PS2
Related Functions: RAD_IOPQueueAsyncOpenFile, RAD_IOPQueueAsyncReadAtBottom, RAD_IOPQueueAsyncReadAtTop
Related Basic Types: U32


RAD_IOPQueueAsyncReadAtTop

The function RAD_IOPQueueAsyncReadAtTop queues an asynchronous read to be performed in the background at the highest priority.

S32 RAD_IOPQueueAsyncReadAtTop(
  RAD_IOP_ASYNC_READ_DATA *read_data
);

Out Parameters

read_data
Specifies the information about the file read to perform.

Returns

Returns non-zero if the read was scheduled, or zero for failure.

Discussion

This function schedules a read to be performed in the background. It will run at the highest priority (either immediately or directly after the current read finishes). You can read from a CD, DVD, the host, a hard drive, IOP memory, or SPU memory. You can read into EE, IOP or SPU destination memory addresses.

You set the file_handle, offset, bytes_to_read, dest, callback, and optionally the group fields in the read_data structure before calling this function. RAD_IOP will then instruct the IOP to perform the read in the background. When the read is complete, the status will be updated, and then the callback made (if you set one).

If you don't have a callback set, then you can spin on the status field and wait for it to go greater than or equal to RAD_IOP_STATUS_COMPLETE. You then query the status for RAD_IOP_STATUS_DONE to determine if the read succeeded.

If the callback is set, then it is called whether the read succeeded or failed, so check the status field in your callback. The callback is made at interrupt time, so be sure that your callback code is interrupt safe.

If the status returns as RAD_IOP_STATUS_ERROR, then you can call the RAD_IOPGetIOStatus function to query for the error code (which will be the result of sceCdRead for CD or DVD files, or the result of the C runtime read functions for other devices).

The read_data structure must remain valid until the read completes or you cancel the read with one of the CancelAsync functions.

You can do your own reads with this function while Bink or Miles is playing to load data in the background while a movie is playing. Load in nice big chunks so that the CD does the minimum amount of seeking back and forth. A good amount to read at one time is a value of one third of your data rate.

You can also do your own reading while we are streaming as long as you do a sceCdSync before each CD read to obtain access to the CD device.

You can also use this function to copy from IOP or SPU memory to IOP, SPU, or EE memory. Just create a file handle for the IOP or SPU memory address using RAD_IOPGetFileHandleToIOPMemory or RAD_IOPGetFileHandleToSPUMemory, and then use this function with the dest_type field set to the appropriate destination type. For example, to copy from IOP address 0x4500 to SPU address 0x17000, you could do:

RAD_IOP_ASYNC_READ_DATA read={0};
read.file_handle = RAD_IOPGetFileHandleToIOPMemory( 0x4500 );
read.offset = 0;
read.bytes_to_read = 32768;
read.dest = 0x17000;
read.dest_type = RAD_IOP_SPU_ADDRESS;
RAD_IOPQueueAsyncReadAtTop( &read );  // starts the copy

Group:
The RAD_IOP API for the Sony PS2

Related Sections:
Memory management under PlayStation 2

Related Functions:
RAD_IOPGetFileHandleToIOPMemory, RAD_IOPGetFileHandleToLSN, RAD_IOPGetFileHandleToSPUMemory, RAD_IOPGetIOStatus, RAD_IOPQueueAsyncOpenFile, RAD_IOPQueueAsyncReadAtBottom, RAD_IOP_READCALLBACK

Related Basic Types:
RAD_IOP_STATUS_VALUES, S32

Related Structures:
RAD_IOP_ASYNC_READ_DATA

Related FAQs:
On the Sony PS2, how can I use the IOP or SPU memory to hold my audio?


RAD_IOP_ASYNC_READ_DATA

The structure RAD_IOP_ASYNC_READ_DATA is a structure used to perform an asynchronous read.

struct RAD_IOP_ASYNC_READ_DATA
{
  S32 file_handle;
  U32 offset;
  U32 bytes_to_read;
  VOID_PTR dest;
  RAD_IOP_ADDRESS_VALUES dest_type;
  RAD_IOP_READCALLBACK callback;
  U32 group;
  RAD_IOP_STATUS_VALUES status;
  U32 bytes_read;
};

In Members

file_handle
You set to a file handle value from RAD_IOPQueueAsyncOpenFile.
A file handle value is one of two types of values. For CD or DVD files, it is the starting sector number or-ed with 0x80000000. For other files, it is just the value returned from the C runtime open function. This means that you don't have to use this routine at all (if you do your own opens, or you know the starting sector number of your file) - just pass these values directly into the read routines.
offset
You set to the offset into the file to read from.
bytes_to_read
You set to the number of bytes to read.
dest
You set to the address where you want the output bytes.
dest_type
Contains the type of memory address that the dest parameter is, an EE, IOP or SPU memory address.
callback
Specifies a callback that should be made upon completion. If you don't want to be called back, then set this field to zero.
group
Optional. Specifies the group identifier of this open. The group id allows you to cancel I/Os for an entire group of requests, if necessary.

Out Members

status
Contains the current status of the async read.
bytes_read
Contains the total bytes read.

Discussion

This structure is used in the RAD_IOPQueueAsyncReadAtTop and RAD_IOPQueueAsyncReadAtBottom functions to schedule a background file read.

You set the file_handle, offset, bytes_to_read, dest, callback, and optionally the group fields and then submit this structure to one of the async read functions. RAD_IOP will then instruct the IOP to perform the read in the background. When the read is complete, the status will be updated, and then the callback made (if you set one).

If you don't have a callback set, then you can spin on the status field and wait for it to go greater than or equal to RAD_IOP_STATUS_COMPLETE. You then query the status for RAD_IOP_STATUS_DONE to determine if the read succeeded.

If the callback is set, then it is called whether the read succeeded or failed, so check the status field in your callback. The callback is made at interrupt time, so be sure that your callback code is interrupt safe.

If the status returns as RAD_IOP_STATUS_ERROR, then you can call the RAD_IOPGetIOStatus function to query for the error code (which will be the result of sceCdRead for CD or DVD files, or the result of the C runtime read functions for other devices).

The read_data structure must remain valid until the read completes or you cancel the read with one of the CancelAsync functions.

Group: The RAD_IOP API for the Sony PS2
Related Functions: RAD_IOPCancelAsyncRead, RAD_IOPGetIOStatus, RAD_IOPQueueAsyncOpenFile, RAD_IOPQueueAsyncReadAtBottom, RAD_IOPQueueAsyncReadAtTop, RAD_IOP_READCALLBACK
Related Basic Types: RAD_IOP_ADDRESS_VALUES, RAD_IOP_STATUS_VALUES, S32, U32, VOID_PTR


RAD_IOP_ADDRESS_VALUES

The basic type RAD_IOP_ADDRESS_VALUES Specifies the type of memory that you want to read into for the RAD_IOP asynchronous I/O functions.

Fundamental Values

Value | Description
RAD_IOP_EE_ADDRESS | The destination pointer is a normal EE memory address.
RAD_IOP_IOP_ADDRESS | The destination pointer is a IOP memory address.
RAD_IOP_SPU_ADDRESS | The destination pointer is a SPU memory address. When reading to the SPU, we always read a multiple of 64 bytes, destination address must be aligned on a 16-byte boundary.

Discussion

These flags are used with the RAD_IOP async read functions. They let you control where the data is placed after a read.

Group: The RAD_IOP API for the Sony PS2
Related Structures: RAD_IOP_ASYNC_READ_DATA


RAD_IOP_READCALLBACK

The function RAD_IOP_READCALLBACK points to a function that will be called when the async read completes.

void RAD_IOP_READCALLBACK(
  RAD_IOP_ASYNC_READ_DATA const *read_data
);

In Parameters

read_data
Specifies the pointer to the structure that you called RAD_IOPQueueAsyncReadAtTop or RAD_IOPQueueAsyncReadAtBottom with.

Discussion

This function will be called once the read is completed (at interrupt level). Be careful that the code you write in this function is interrupt safe.

This callback will be made for success or failure, so check the status field value to determine whether the read actually succeeded.

Group: The RAD_IOP API for the Sony PS2
Related Functions: RAD_IOPQueueAsyncReadAtBottom, RAD_IOPQueueAsyncReadAtTop
Related Basic Types: void
Related Structures: RAD_IOP_ASYNC_READ_DATA


RAD_IOPQueueAsyncReadAtBottom

The function RAD_IOPQueueAsyncReadAtBottom queues an asynchronous read to be performed in the background at the lowest priority.

S32 RAD_IOPQueueAsyncReadAtBottom(
  RAD_IOP_ASYNC_READ_DATA *read_data
);

Out Parameters

read_data
Specifies the information about the file read to perform.

Returns

Returns non-zero if the read was scheduled, or zero for failure.

Discussion

This function schedules a read to be performed in the background. It will run at the lowest priority (once all other I/O has been performed).

You set the file_handle, offset, bytes_to_read, dest, callback, and optionally the group fields in the read_data structure before calling this function. RAD_IOP will then instruct the IOP to perform the read in the background. When the read is complete, the status will be updated, and then the callback made (if you set one).

If you don't have a callback set, then you can spin on the status field and wait for it to go greater than or equal to RAD_IOP_STATUS_COMPLETE. You then query the status for RAD_IOP_STATUS_DONE to determine if the read succeeded.

If the callback is set, then it is called whether the read succeeded or failed, so check the status field in your callback. The callback is made at interrupt time, so be sure that your callback code is interrupt safe.

If the status returns as RAD_IOP_STATUS_ERROR, then you can call the RAD_IOPGetIOStatus function to query for the error code (which will be the result of sceCdRead for CD or DVD files, or the result of the C runtime read functions for other devices).

The read_data structure must remain valid until the read completes or you cancel the read with one of the CancelAsync functions.

You can do your own reads with this function while we are streaming (to load data in the background). Load in nice big chunks so that the CD does the minimum amount of seeking back and forth. A good amount to read at one time is a value of one third of your data rate.

You can also do your own reading while we are streaming as long as you do a sceCdSync before each CD read to obtain access to the CD device.

You can also use this function to copy from IOP or SPU memory to IOP, SPU, or EE memory. Just create a file handle for the IOP or SPU memory address using RAD_IOPGetFileHandleToIOPMemory or RAD_IOPGetFileHandleToSPUMemory, and then use this function with the dest_type field set to the appropriate destination type. For example, to copy from IOP address 0x4500 to SPU address 0x17000, you could do:

RAD_IOP_ASYNC_READ_DATA read={0};
read.file_handle = RAD_IOPGetFileHandleToIOPMemory(0x4500);
read.offset = 0;
read.bytes_to_read = 32768;
read.dest = 0x17000;
read.dest_type = RAD_IOP_SPU_ADDRESS;
RAD_IOPQueueAsyncReadAtTop( &read );  // starts the copy

Group:
The RAD_IOP API for the Sony PS2

Related Functions:
RAD_IOPGetFileHandleToIOPMemory, RAD_IOPGetFileHandleToLSN, RAD_IOPGetFileHandleToSPUMemory, RAD_IOPGetIOStatus, RAD_IOPQueueAsyncOpenFile, RAD_IOPQueueAsyncReadAtBottom, RAD_IOPQueueAsyncReadAtTop, RAD_IOP_READCALLBACK

Related Basic Types:
RAD_IOP_STATUS_VALUES, S32

Related Structures:
RAD_IOP_ASYNC_READ_DATA


RAD_IOPGetIOStatus

The function RAD_IOPGetIOStatus returns the error code from a failed IO request.

S32 RAD_IOPGetIOStatus();

Returns

Returns the error code. This will be either the result of sceCdRead or the C runtime read function depending on the device you are playing from.

Discussion

This function will return the error code when a background file read fails with a RAD_IOP_STATUS_ERROR code. If you are playing off the CD or DVD, then the value will be the result of the sceCdRead function. On other devices, the result will be the result of the C runtime read function.

Group: The RAD_IOP API for the Sony PS2
Related Functions: RAD_IOPQueueAsyncReadAtBottom, RAD_IOPQueueAsyncReadAtTop
Related Basic Types: RAD_IOP_STATUS_VALUES, S32
Related Structures: RAD_IOP_ASYNC_READ_DATA


RAD_IOPCancelAsyncOpen

The function RAD_IOPCancelAsyncOpen cancels a previous asynchronous file open.

S32 RAD_IOPCancelAsyncOpen(
  RAD_IOP_ASYNC_OPEN_DATA  const *open_data
);

In Parameters

open_data
Specifies the file open to cancel.

Returns

Returns how many async operations were cancelled (if zero, then that usually means it had already completed).

Discussion

This function allows you to cancel a previously queued file open request. Note that callbacks are still made when an open request is cancelled - make sure you check the status field.

Group: The RAD_IOP API for the Sony PS2
Related Functions: RAD_IOPCancelAllAsyncs, RAD_IOPCancelGroupOfAsyncs
Related Basic Types: S32
Related Structures: RAD_IOP_ASYNC_OPEN_DATA


RAD_IOPCancelAsyncRead

The function RAD_IOPCancelAsyncRead cancels a previous asynchronous file read.

S32 RAD_IOPCancelAsyncRead(
  RAD_IOP_ASYNC_READ_DATA const *open_data
);

In Parameters

open_data
Specifies the file read to cancel.

Returns

Returns how many async operations were cancelled (if zero, then that usually means it had already completed).

Discussion

This function allows you to cancel a previously queued file read request. Note that callbacks are still made when an open request is cancelled - make sure you check the status field.

Group: The RAD_IOP API for the Sony PS2
Related Functions: RAD_IOPCancelAllAsyncs, RAD_IOPCancelFileAsyncs, RAD_IOPCancelGroupOfAsyncs
Related Basic Types: S32
Related Structures: RAD_IOP_ASYNC_READ_DATA


RAD_IOPCancelFileAsyncs

The function RAD_IOPCancelFileAsyncs cancels all previous asynchronous file reads for a specified file handle.

S32 RAD_IOPCancelFileAsyncs(
  S32 file_handle
);

In Parameters

file_handle
Specifies the file handle to cancel the reads for.

Returns

Returns how many async operations were cancelled (if zero, then that usually means it had already completed).

Discussion

This function allows you to cancel all previously queued file read requests for a specific file handle. Note that callbacks are still made when an open request is cancelled - make sure you check the status field.

Group: The RAD_IOP API for the Sony PS2
Related Functions: RAD_IOPCancelAllAsyncs, RAD_IOPCancelAsyncRead, RAD_IOPCancelGroupOfAsyncs
Related Basic Types: S32


RAD_IOPCancelGroupOfAsyncs

The function RAD_IOPCancelGroupOfAsyncs cancels all previous asynchronous file opens and reads for a specified group id.

S32 RAD_IOPCancelGroupOfAsyncs(
  U32 group
);

In Parameters

group
Specifies the group id handle to cancel the opens and reads for.

Returns

Returns how many async operations were cancelled (if zero, then that usually means it had already completed).

Discussion

This function allows you to cancel all previously queued file open and read requests for a specific group id. Note that callbacks are still made when an open request is cancelled - make sure you check the status field.

Group: The RAD_IOP API for the Sony PS2
Related Functions: RAD_IOPCancelAllAsyncs, RAD_IOPCancelAsyncOpen, RAD_IOPCancelAsyncRead, RAD_IOPCancelFileAsyncs
Related Basic Types: S32, U32


RAD_IOPCancelAllAsyncs

The function RAD_IOPCancelAllAsyncs cancels all previous asynchronous file opens and reads.

S32 RAD_IOPCancelAllAsyncs();

Returns

Returns how many async operations were cancelled (if zero, then that usually means it had already completed).

Discussion

This function allows you to cancel all previously queued file open and read requests. Note that callbacks are still made when an open request is cancelled - make sure you check the status field.

Group: The RAD_IOP API for the Sony PS2
Related Functions: RAD_IOPCancelAllAsyncs, RAD_IOPCancelAsyncOpen, RAD_IOPCancelAsyncRead, RAD_IOPCancelFileAsyncs, RAD_IOPCancelGroupOfAsyncs
Related Basic Types: S32


RAD_IOPCloseFile

The function RAD_IOPCloseFile closes a file handle opened with RAD_IOPQueueAsyncOpenFile.

S32 RAD_IOPCloseFile(
  S32 file_handle
);

In Parameters

file_handle
Specifies the file handle to close.

Returns

Returns non-zero if the close was successful, or zero on failure.

Discussion

Use this function to close file handles that you previously opened. All outstanding async reads for the file will be cancelled (and the callbacks will still be made).

Group: The RAD_IOP API for the Sony PS2
Related Functions: RAD_IOPQueueAsyncOpenFile
Related Basic Types: S32


RAD_IOPRegisterSoundCallback

The function RAD_IOPRegisterSoundCallback registers a sound data structure to call your sound interrupt callback.

S32 RAD_IOPRegisterSoundCallback(
  RAD_IOP_SOUND_DATA *sound_data
);

Out Parameters

sound_data
Specifies the sound callback information.

Returns

Returns non-zero if the sound callback was registered, or zero on failure.

Discussion

This function registers a sound callback structure to call a sound interrupt callback. The sound callbacks won't actually start until a call to RAD_IOPStartSound.

This structure must remain valid until the sound callback is unregistered with the RAD_IOPUnregisterSoundCallback function.

The sound callback function is called at interrupt time, so make sure your code is interrupt safe.

Each time your sound callback is made, you must overwrite or mix sound data into the buffer that is specified by the address and length fields in the sound_data structure. The overwrite flag in the sound_data structure says whether you should copy your data directly into the buffer (if overwrite is true), or whether you should mix your data into the buffer (if overwrite is false). To mix, just add your S16 values with the S16 values that are already in the buffer (clamping at -32768 and 32767).

Normally, the buffer is a 48,000 Hz, 16-bit, stereo PCM data block which is formatted in the Sony style of 256 left samples followed by 256 right samples. The length will always be a multiple of 512 samples (in the current version of RAD_IOP, it will be 2,048 bytes). When the RAD_IOP_SPDIF + RAD_IOP_NEED_CORE0 flags are used, the data block returned by the EE is treated as raw bitstream data, typically destined for a DTS receiver. (The callback's overwrite flag is not meaningful in RAD_IOP_SPDIF mode.)

Group: The RAD_IOP API for the Sony PS2
Related Functions: RAD_IOPStartSound, RAD_IOPUnregisterSoundCallback, RAD_IOPUnregisterTimerCallback
Related Basic Types: S32
Related Structures: RAD_IOP_SOUND_DATA


RAD_IOP_SOUND_DATA

The structure RAD_IOP_SOUND_DATA is a structure used to control a sound interrupt callback.

struct RAD_IOP_SOUND_DATA
{
  U32 which_sound_core;
  RAD_IOP_SOUNDCALLBACK callback;
  S32 overwrite;
  VOID_PTR address;
  U32 length;
  RAD_IOP_STATUS_VALUES status;
};

In Members

which_sound_core
Specifies which sound core to register for (you must have requested this core in the RAD_IOPStartUp call.
callback
Specifies the sound callback function address.

Out Members

overwrite
Flag that says whether to overwrite the sound address data (non-zero), or to mix your sound data into the buffer (zero).
address
Contains the address that the callback should fill with sound.
length
Contains the length in bytes that you must fill each callback.
status
Contains the current status of the sound callback.

Discussion

This structure contains the data to call a sound interrupt callback. It must remain valid until the sound callback is unregistered.

Each time your sound callback is made, you must overwrite or mix sound data into the buffer that is specified by the address and length fields in the sound_data structure. The overwrite flag in the sound_data structure says whether you should copy your data directly into the buffer (if overwrite is true), or whether you should mix your data into the buffer (if overwrite is false). To mix, just add your S16 values with the S16 values that are already in the buffer (clamping at -32768 and 32767).

Normally, the buffer is a 48,000 Hz, 16-bit, stereo PCM data block which is formatted in the Sony style of 256 left samples followed by 256 right samples. The length will always be a multiple of 512 samples (in the current version of RAD_IOP, it will be 2,048 bytes). When the RAD_IOP_SPDIF + RAD_IOP_NEED_CORE0 flags are used, the data block returned by the EE is treated as raw bitstream data, typically destined for a DTS receiver. The overwrite flag is not meaningful in RAD_IOP_SPDIF mode.

Group: The RAD_IOP API for the Sony PS2
Related Functions: RAD_IOPPauseSound, RAD_IOPRegisterSoundCallback, RAD_IOPStartSound, RAD_IOPStartUp, RAD_IOPUnregisterSoundCallback, RAD_IOP_SOUNDCALLBACK
Related Basic Types: RAD_IOP_STATUS_VALUES, S32, U32, VOID_PTR
Related Structures: RAD_IOP_SOUND_DATA


RAD_IOP_SOUNDCALLBACK

The function RAD_IOP_SOUNDCALLBACK points to a function that will be called periodically to fill a streaming sound buffer.

void RAD_IOP_SOUNDCALLBACK(
  RAD_IOP_SOUND_DATA const *sound_data
);

In Parameters

sound_data
Specifies the pointer to the structure that you called RAD_IOPRegisterSoundCallback with.

Discussion

This function will be called periodically to fill the sound buffer.

Each time your sound callback is made, you must overwrite or mix sound data into the buffer that is specified by the address and length fields in the sound_data structure. The overwrite flag in the sound_data structure says whether you should copy your data directly into the buffer (if overwrite is true), or whether you should mix your data into the buffer (if overwrite is false). To mix, just add your S16 values with the S16 values that are already in the buffer (clamping at -32768 and 32767).

Normally, the buffer is a 48,000 Hz, 16-bit, stereo PCM data block which is formatted in the Sony style of 256 left samples followed by 256 right samples. The length will always be a multiple of 512 samples (in the current version of RAD_IOP, it will be 2,048 bytes). When the RAD_IOP_SPDIF + RAD_IOP_NEED_CORE0 flags are used, the data block returned by the EE is treated as raw bitstream data, typically destined for a DTS receiver. (The callback's overwrite flag is not meaningful in RAD_IOP_SPDIF mode.)

Group: The RAD_IOP API for the Sony PS2
Related Basic Types: void
Related Structures: RAD_IOP_SOUND_DATA


RAD_IOPStartSound

The function RAD_IOPStartSound starts calling a previously registered sound callback.

S32 RAD_IOPStartSound(
  RAD_IOP_SOUND_DATA *sound_data
);

Out Parameters

sound_data
Specifies the sound callback to control.

Returns

Returns non-zero on success, or zero on failure.

Discussion

This function tells RAD_IOP to start calling your sound callback. Each time you are called, you are expected to fill the address with sound data as quickly as possible and then return.

The callback is made at interrupt time, so make sure your callback only uses interrupt safe code.

Group: The RAD_IOP API for the Sony PS2
Related Functions: RAD_IOPPauseSound, RAD_IOPRegisterSoundCallback
Related Basic Types: S32
Related Structures: RAD_IOP_SOUND_DATA


RAD_IOPPauseSound

The function RAD_IOPPauseSound pauses a previously registered sound callback.

S32 RAD_IOPPauseSound(
  RAD_IOP_SOUND_DATA *sound_data
);

Out Parameters

sound_data
Specifies the sound callback to control.

Returns

Returns non-zero on success, or zero on failure.

Discussion

This function tells RAD_IOP to stop calling your sound callback.

Group: The RAD_IOP API for the Sony PS2
Related Functions: RAD_IOPStartSound
Related Basic Types: S32
Related Structures: RAD_IOP_SOUND_DATA


RAD_IOPUnregisterSoundCallback

The function RAD_IOPUnregisterSoundCallback unregisters a sound callback.

S32 RAD_IOPUnregisterSoundCallback(
  RAD_IOP_SOUND_DATA *sound_data
);

Out Parameters

sound_data
Specifies the sound callback structure to unregister.

Returns

Returns non-zero on success, or zero on failure.

Discussion

This function stops a sound callback and unregisters the sound callback structure.

Always call this function before freeing the memory passed to RAD_IOPRegisterSoundCallback.

Group: The RAD_IOP API for the Sony PS2
Related Functions: RAD_IOPRegisterSoundCallback
Related Basic Types: S32
Related Structures: RAD_IOP_SOUND_DATA


RAD_IOPRegisterTimerCallback

The function RAD_IOPRegisterTimerCallback registers a timer structure to call your timer interrupt callback at a certain frequency.

S32 RAD_IOPRegisterTimerCallback(
  RAD_IOP_TIMER_DATA *timer_data
);

Out Parameters

timer_data
Specifies the callback information.

Returns

Returns non-zero if the timer was registered, or zero on failure.

Discussion

This function registers a timer callback structure to call a timer interrupt callback. The timer won't actually start until a call to RAD_IOPStartTimer.

This structure must remain valid until the timer is unregistered with the RAD_IOPUnregisterTimerCallback function.

The timer callback function is called at interrupt time, so make sure your code is interrupt safe.

Group: The RAD_IOP API for the Sony PS2
Related Functions: RAD_IOPStartTimer, RAD_IOPUnregisterTimerCallback, RAD_IOP_TIMERCALLBACK
Related Basic Types: S32
Related Structures: RAD_IOP_TIMER_DATA


RAD_IOP_TIMER_DATA

The structure RAD_IOP_TIMER_DATA is a structure used to call a timer interrupt callback.

struct RAD_IOP_TIMER_DATA
{
  RAD_IOP_TIMERCALLBACK callback;
  RAD_IOP_STATUS_VALUES status;
};

In Members

callback
Specifies the timer callback function address.

Out Members

status
Contains the current status of the timer.

Discussion

This structure contains the data to call a timer interrupt callback. It must remain valid until the timer is unregistered.

Group: The RAD_IOP API for the Sony PS2
Related Functions: RAD_IOPPauseTimer, RAD_IOPRegisterTimerCallback, RAD_IOPStartTimer, RAD_IOPUnregisterTimerCallback, RAD_IOP_TIMERCALLBACK
Related Basic Types: RAD_IOP_STATUS_VALUES


RAD_IOP_TIMERCALLBACK

The function RAD_IOP_TIMERCALLBACK points to a function that will be called periodically.

void RAD_IOP_TIMERCALLBACK(
  RAD_IOP_TIMER_DATA const *timer_data
);

In Parameters

timer_data
Specifies the pointer to the structure that you called RAD_IOPRegisterTimerCallback with.

Discussion

This function will be called once after calling the RAD_IOPStartTimer function. The callback will be made at interrupt time, so be careful that the code you write in this function is interrupt safe.

Group: The RAD_IOP API for the Sony PS2
Related Functions: RAD_IOPRegisterTimerCallback, RAD_IOPStartTimer
Related Basic Types: void
Related Structures: RAD_IOP_TIMER_DATA


RAD_IOPStartTimer

The function RAD_IOPStartTimer starts calling a previously registered timer callback.

U32 RAD_IOPStartTimer(
  RAD_IOP_TIMER_DATA *timer_data,
  U32 ms_between
);

In Parameters

ms_between
Specifies the millisecond between each call. For example, if you wanted a timer that is called 100 times per second, then you'd use 10 ms.

Out Parameters

timer_data
Specifies the timer to control.

Returns

Returns the current internal timer period (or zero if there was an error).

Discussion

This function tells RAD_IOP to start calling your timer callback. You can call it multiple times to change the timer period.

These timers are drift-free, that is, they keep track of the last time they were called and make sure the average millisecond period that you requested is maintained.

Internally, RAD_IOP only uses one hardware timer and set it's frequency to the faster timer that you request. So, if you request a 10 ms timer and a 5 ms timer, the internal timer will run at 5 ms, and the 10 ms will only be called every other time.

Group: The RAD_IOP API for the Sony PS2
Related Functions: RAD_IOPPauseTimer, RAD_IOPRegisterTimerCallback, RAD_IOP_TIMERCALLBACK
Related Basic Types: U32
Related Structures: RAD_IOP_TIMER_DATA


RAD_IOPPauseTimer

The function RAD_IOPPauseTimer pauses a previously registered timer callback.

S32 RAD_IOPPauseTimer(
  RAD_IOP_TIMER_DATA *timer_data
);

Out Parameters

timer_data
Specifies the timer to control.

Returns

Returns non-zero on success, or zero on failure.

Discussion

This function tells RAD_IOP to stop calling your timer callback.

Group: The RAD_IOP API for the Sony PS2
Related Functions: RAD_IOPStartTimer
Related Basic Types: S32
Related Structures: RAD_IOP_TIMER_DATA


RAD_IOPUnregisterTimerCallback

The function RAD_IOPUnregisterTimerCallback unregisters a timer callback.

S32 RAD_IOPUnregisterTimerCallback(
  RAD_IOP_TIMER_DATA *timer_data
);

Out Parameters

timer_data
Specifies the timer structure to unregister.

Returns

Returns non-zero on success, or zero on failure.

Discussion

This function stops a background timer and unregisters the timer callback structure.

Always call this function before freeing the memory passed to RAD_IOPRegisterTimerCallback.

Group: The RAD_IOP API for the Sony PS2
Related Functions: RAD_IOPRegisterSoundCallback, RAD_IOPRegisterTimerCallback
Related Basic Types: S32
Related Structures: RAD_IOP_TIMER_DATA


RAD_IOPHardwareVolumes

The function RAD_IOPHardwareVolumes sets the sound core hardware volumes.

S32 RAD_IOPHardwareVolumes(
  U32 which_core,
  S32 master_core_left,
  S32 master_core_right,
  S32 pcm_channel_left,
  S32 pcm_channel_right
);

In Parameters

which_core
Specifies a 0 or 1 for which of the sound cores to control.
master_core_left
Specifies a linear volume level from 0 to 0x3fff for the core's master left speaker out. If you don't want to set this volume level, pass -1.
master_core_right
Specifies a linear volume level from 0 to 0x3fff for the core's master right speaker out. If you don't want to set this volume level, pass -1.
pcm_channel_left
Specifies a linear volume level from 0 to 0x7fff for the pcm channel's left speaker out. If you don't want to set this volume level, pass -1.
pcm_channel_right
Specifies a linear volume level from 0 to 0x7fff for the pcm channel's right speaker out. If you don't want to set this volume level, pass -1.

Returns

Returns non-zero on success, or zero on failure.

Discussion

This function sets the hardware sound volumes. Unless you have previously set the master volumes, you will need to call this function at least once to establish the levels.

The master volume controls the volume of all voices on that chip (including the ADPCM voices). The pcm channel volume just sets the pcm channel. All Bink and Miles voices use the same IOP voice, so you should use this function to just set baselines, and then use normal Bink or Miles function calls to set volumes on a per-source basis.

Note that sound core 0 feeds into sound core 1, so if you use core 0, then you also have to turn the core 1 master volume, or you won't hear anything.

Group: The RAD_IOP API for the Sony PS2
Related Basic Types: S32, U32


RADTimerRead

The function RADTimerRead returns a rolling millisecond timer.

U32 RADTimerRead();

Returns

Returns a new millisecond count.

Discussion

This function just gives you a millisecond count. It wraps around every 49 days or so.

Group: The RAD_IOP API for the Sony PS2
Related Basic Types: U32


The RAD_IOP SPU Hardware Voice API for the Sony PS2

Discussion

The Sony PS2 has two audio hardware cores, called the "SPUs", that can each decode 24 ADPCM sound samples. Each SPU can also play one uncompressed PCM stream (which Miles and Bink use for their high-level audio output). As an alternative to the Miles and Bink high-level APIs, the RAD_IOP Hardware Voice API may be used to control the 48 ADPCM voices directly.

The ADPCM hardware is nice because it doesn't use any EE or IOP cycles or any EE or IOP RAM. There are downsides, though -- the hardware is pretty basic. It can only play mono ADPCM voices, and runtime control is rudimentary.

The SPUs are easy to program because they are so simple. Each SPU plays its 24 voices constantly. In fact, you don't really start and stop this hardware - if you want to stop audio playback, for example, you simply turn down the volume or point the playback at silence data. This is kind of weird, but since it's hardware, it costs nothing.

Our SPU API operates on the voices at a very low level, and it operates on them in parallel. That is, every SPU voice function can operate on any one or all of the 48 voices at once. For example, you can set the pitch of all 48 voices in a single call, if you choose to.

Since the voice resources are fixed, you don't "allocate" a voice - you simply start using its bit mask. For example, the bit mask for voice 23 is "1 << 23", so you just use that constant when you want to do something with voice 23. If you want to find a voice that isn't playing anything, then you can use the RAD_IOPQueueAsyncSPUGlobalState and RAD_IOPFindNonPlayingVoiceMask functions to find one, or you can just keep track of which voices are active as you use them. This is a lower-level approach than an API like Miles offers, but it's also easy, fast and reflects the way that the hardware actually works.

Similar to the non-allocation-based voice policy, the Sony system software doesn't use an API for allocating and freeing SPU RAM. You are expected to manage this yourself. SPU RAM for game use starts at address 0x5100 and ends at address 0x1fffff (roughly 2 MB). Most games simply start allocating memory with a linear allocator at offset 0x5100 at the start of each level, and then flush back to 0x5100 at the start of the next level.

You can use the RAD_IOP async IO functions (described in the previous chapter) to load the actual audio data files. Sony calls SPU-compatible audio files "VAG" files, and they use a simple ADPCM compression scheme. You use the VAGEdit utility to convert WAV files into VAG files. VAG files are very simple - there is a 48-byte header, followed by the sound data itself. Most people don't even read the header, since all you need is the pitch and that's generally a game-wide setting. So, most games simply skip the 48-byte header completely, and just load the audio data.

Although this all seems very low-level, it is actually quite simple (and easier to understand in code than the docs). See the MilesPS2.cpp example program for a demonstration.

The rest of this section will describe the SPU voice APIs.

The RAD_IOP SPU Hardware Voice API for the Sony PS2
RAD_IOPSetSPUVoiceStartAddress | sets the address to play from for one or more SPU voices.
RAD_IOPSetSPUVoiceLoopAddress | sets the address to loop back to for one or more SPU voices.
RAD_IOPSetSPUVoiceVolume | sets the volume for one or more SPU voices.
RAD_IOPSetSPUVoicePitch | sets the pitch for one or more SPU voices.
RAD_IOPSetSPUVoiceADSR | sets the envelope for one or more SPU voices.
RAD_IOPSetSPUVoiceMixOnOff | sets the mix on-off routing for one or more SPU voices.
RAD_IOPSetSPUVoiceOnOff | starts or stops the playback of one or more SPU voices.
RAD_IOPQueueAsyncSPUVoiceState | asynchronously queries the state of an SPU voice.
RAD_IOP_SPU_VOICE_STATE | is a structure used with the RAD_IOPQueueAsyncSPUVoiceState function.
RAD_IOP_SPU_VOICE_STATE_CALLBACK | points to a function that will be called when the async query completes.
RAD_IOPQueueAsyncSPUGlobalState | asynchronously queries the state of the SPU cores.
RAD_IOP_SPU_GLOBAL_STATE | is a structure used with the RAD_IOPQueueAsyncSPUGlobalState function.
RAD_IOP_SPU_GLOBAL_STATE_CALLBACK | points to a function that will be called when the async query completes.
RAD_IOPFindNonPlayingVoiceMask | returns a bitmask that corresponds to a single non-playing voice.


RAD_IOPSetSPUVoiceStartAddress

The function RAD_IOPSetSPUVoiceStartAddress sets the address to play from for one or more SPU voices.

S32 RAD_IOPSetSPUVoiceStartAddress(
  U32 core0_voice_mask,
  U32 core1_voice_mask,
  U32 start_address
);

In Parameters

core0_voice_mask
Specifies the bit mask of the voices on core 0 to set.
core1_voice_mask
Specifies the bit mask of the voices on core 1 to set.
start_address
Specifies the starting address in SPU RAM to begin playback at.

Returns

Returns non-zero on success, or zero on failure.

Discussion

This function tells the SPU where to begin playback for one or more SPU voices.

Usually, you will load the VAG file into an SPU RAM address with one of the RAD_IOP async IO calls and then use this function to point one or more voices at it.

Group: The RAD_IOP SPU Hardware Voice API for the Sony PS2
Related Functions: RAD_IOPSetSPUVoiceLoopAddress, RAD_IOPSetSPUVoiceOnOff
Related Basic Types: S32, U32


RAD_IOPSetSPUVoiceLoopAddress

The function RAD_IOPSetSPUVoiceLoopAddress sets the address to loop back to for one or more SPU voices.

S32 RAD_IOPSetSPUVoiceLoopAddress(
  U32 core0_voice_mask,
  U32 core1_voice_mask,
  U32 loop_address
);

In Parameters

core0_voice_mask
Specifies the bit mask of the voices on core 0 to set.
core1_voice_mask
Specifies the bit mask of the voices on core 1 to set.
loop_address
Specifies the loop address in SPU RAM to loop back to.

Returns

Returns non-zero on success, or zero on failure.

Discussion

This function tells the SPU where to jump to when the end of playback is hit.

Unlike most sound systems, you tell the SPU to loop or not to loop in the source files. That is, inside VAGEdit, you choose whether the sound is going to be looped or not. If the sound is looped, then you can use this function to change where in SPU RAM to jump to when you hit the end of a buffer.

Since it's nice to be able to choose looping or non-looping at run-time, there is a clever trick you can use. When you create your VAG files, always make them in looping mode. Now when you do this, all of your sound samples will loop forever. However, the trick is to set the loop address back to a special SPU address that contains silence data! So, the sound plays once, and then jumps back to the SPU silence address and then just plays silence from then on.

So, this way, you can choose to loop or not loop the sound based on whether you set the loop address to the SPU silence address. You can see the MilesPS2.c example program for an example of this technique - it is much simpler than it sounds. RAD_IOP defines the constant SPU_SILENCE_ADDRESS to refer to the SPU silence address.

Group: The RAD_IOP SPU Hardware Voice API for the Sony PS2
Related Functions: RAD_IOPSetSPUVoiceStartAddress
Related Basic Types: S32, U32


RAD_IOPSetSPUVoiceVolume

The function RAD_IOPSetSPUVoiceVolume sets the volume for one or more SPU voices.

S32 RAD_IOPSetSPUVoiceVolume(
  U32 core0_voice_mask,
  U32 core1_voice_mask,
  S32 left,
  S32 right
);

In Parameters

core0_voice_mask
Specifies the bit mask of the voices on core 0 to set.
core1_voice_mask
Specifies the bit mask of the voices on core 1 to set.
left
Specifies the left speaker volume from 0 to 0x3fff, or -1 to leave unchanged.
right
Specifies the right speaker volume from 0 to 0x3fff, or -1 to leave unchanged.

Returns

Returns non-zero on success, or zero on failure.

Discussion

This function tells the SPU to set the baseline volume of one or more SPU voices.

The final volume level is further controlled by the envelope settings and the master volume levels.

Group: The RAD_IOP SPU Hardware Voice API for the Sony PS2
Related Functions: RAD_IOPSetSPUVoiceADSR
Related Basic Types: S32, U32


RAD_IOPSetSPUVoicePitch

The function RAD_IOPSetSPUVoicePitch sets the pitch for one or more SPU voices.

S32 RAD_IOPSetSPUVoicePitch(
  U32 core0_voice_mask,
  U32 core1_voice_mask,
  U32 pitch
);

In Parameters

core0_voice_mask
Specifies the bit mask of the voices on core 0 to set.
core1_voice_mask
Specifies the bit mask of the voices on core 1 to set.
pitch
Specifies the pitch to use.

Returns

Returns non-zero on success, or zero on failure.

Discussion

This function tells the SPU to set the pitch of one or more SPU voices.

Pitch is not the same as the frequency or playback rate of the sound. Pitch here is defined as "( freq * 4096 ) / 48000". So, to set a playback rate of 22050, you would use 22050 * 4096 / 48000, or 1882.

The best way to pause a playing SPU voice is to set its pitch to 0. This effectively pauses the sound playback position until you resume it by setting the original pitch again.

Group: The RAD_IOP SPU Hardware Voice API for the Sony PS2
Related Basic Types: S32, U32


RAD_IOPSetSPUVoiceADSR

The function RAD_IOPSetSPUVoiceADSR sets the envelope for one or more SPU voices.

S32 RAD_IOPSetSPUVoiceADSR(
  U32 core0_voice_mask,
  U32 core1_voice_mask,
  U32 adsr1,
  U32 adsr2
);

In Parameters

core0_voice_mask
Specifies the bit mask of the voices on core 0 to set.
core1_voice_mask
Specifies the bit mask of the voices on core 1 to set.
adsr1
Specifies the first envelope bit pattern.
adsr2
Specifies the second envelope bit pattern.

Returns

Returns non-zero on success, or zero on failure.

Discussion

This function tells the SPU to set the volume envelope of one or more SPU voices.

The envelope bit patterns are fairly complicated and are basically a big set of table indexes encoded into two 32-bit words. If you want to set a voice envelope, you should refer to the Sony docs directly.

For a simple, instant-on, full sustain, and instant-fall-off envelope, use 0x000f for adsr1, and 0x1fc0 for adsr2.

Group: The RAD_IOP SPU Hardware Voice API for the Sony PS2
Related Functions: RAD_IOPSetSPUVoiceOnOff, RAD_IOPSetSPUVoiceVolume
Related Basic Types: S32, U32


RAD_IOPSetSPUVoiceMixOnOff

The function RAD_IOPSetSPUVoiceMixOnOff sets the mix on-off routing for one or more SPU voices.

S32 RAD_IOPSetSPUVoiceMixOnOff(
  U32 core0_voice_mask,
  U32 core1_voice_mask,
  S32 dry_left_onoff,
  S32 dry_right_onoff,
  S32 wet_left_onoff,
  S32 wet_right_onoff
);

In Parameters

core0_voice_mask
Specifies the bit mask of the voices on core 0 to set.
core1_voice_mask
Specifies the bit mask of the voices on core 1 to set.
dry_left_onoff
1 steers the voice to the left speaker dry path; 0 steers the voice away from the left dry path; -1 means leave unchanged.
dry_right_onoff
1 steers the voice to the right speaker dry path; 0 steers the voice away from the right dry path; -1 means leave unchanged.
wet_left_onoff
1 steers the voice to the left speaker wet path; 0 steers the voice away from the left wet path; -1 means leave unchanged.
wet_right_onoff
1 steers the voice to the right speaker wet path; 0 steers the voice away from the right wet path; -1 means leave unchanged.

Returns

Returns non-zero on success, or zero on failure.

Discussion

This function tells the SPU to route one or more SPU voices to specific sound outputs.

The dry left and right settings control whether to send this voice to the non-reverb path. The wet left and right settings control whether to send this voice to the reverb path.

By default, the voices are configured to go to the dry left and right only.

Group: The RAD_IOP SPU Hardware Voice API for the Sony PS2
Related Basic Types: S32, U32


RAD_IOPSetSPUVoiceOnOff

The function RAD_IOPSetSPUVoiceOnOff starts or stops the playback of one or more SPU voices.

S32 RAD_IOPSetSPUVoiceOnOff(
  U32 core0_voice_mask,
  U32 core1_voice_mask,
  S32 onoff
);

In Parameters

core0_voice_mask
Specifies the bit mask of the voices on core 0 to start or stop.
core1_voice_mask
Specifies the bit mask of the voices on core 1 to start or stop.
onoff
Use 1 to start the specified voices, or 0 to stop the specified voices.

Returns

Returns non-zero on success, or zero on failure.

Discussion

This function tells the SPU to begin or stop playback of one or more SPU voices.

In practice, you can just think of this function starting and stopping the voice, but that's not exactly what happens at the hardware level.

In fact, it's kind of weird to say a voice is "started" or "stopped" in the SPU hardware at all, because the voices are always decoding data. It's more accurate to stay that when you start a sound, you are telling the hardware to jump to the starting address set with RAD_IOPSetSPUVoiceStartAddress and to begin the volume envelope specified by RAD_IOPSetSPUVoiceADSR. When you stop a sound, you are really just telling the hardware to begin the release portion of the envelope (which generally just cranks the audio volume down to zero, so that it seems like playback has stopped).

Group: The RAD_IOP SPU Hardware Voice API for the Sony PS2
Related Functions: RAD_IOPSetSPUVoiceADSR, RAD_IOPSetSPUVoiceStartAddress
Related Basic Types: S32, U32


RAD_IOPQueueAsyncSPUVoiceState

The function RAD_IOPQueueAsyncSPUVoiceState asynchronously queries the state of an SPU voice.

S32 RAD_IOPQueueAsyncSPUVoiceState(
  RAD_IOP_SPU_VOICE_STATE *state_data
);

Out Parameters

state_data
Specifies the input and output parameters for the voice state.

Returns

Non-zero if the query was queued successfully, zero for failure.

Discussion

This function queues up a voice query to happen in the background.

You fill out the core field, voice field, and optionally the callback field (or set it to zero), and then call this function.

You can check for completion using the callback, or just poll the status field. If the status is set to RAD_IOP_STATUS_DONE, then the current state fields have been set correctly.

You can use this field to see where the current playback position is, to see whether the voice is still playing, or to check the current envelope level.

Group: The RAD_IOP SPU Hardware Voice API for the Sony PS2
Related Functions: RAD_IOPQueueAsyncSPUGlobalState, RAD_IOP_SPU_VOICE_STATE_CALLBACK
Related Basic Types: RAD_IOP_STATUS_VALUES, S32
Related Structures: RAD_IOP_SPU_VOICE_STATE


RAD_IOP_SPU_VOICE_STATE

The structure RAD_IOP_SPU_VOICE_STATE is a structure used with the RAD_IOPQueueAsyncSPUVoiceState function.

struct RAD_IOP_SPU_VOICE_STATE
{
  U32 core;
  U32 voice;
  RAD_IOP_SPU_VOICE_STATE_CALLBACK callback;
  RAD_IOP_STATUS_VALUES status;
  S32 current_playing;
  U32 current_address;
  U32 current_left_volume;
  U32 current_right_volume;
  U32 current_envelope;
};

In Members

core
Specifies the core to query - either 0 or 1.
voice
Specifies the voice to query - from 0 to 24. Note that this isn't a voice mask, but a voice index, since you only query one voice at a time.
callback
Specifies a callback that should be made upon completion. If you don't want to be called back, then set this field to zero.

Out Members

status
Contains the current status of the async status.
current_playing
1 if playing, 0 if not playing (i.e., the voice envelope hasn't entered its release phase yet).
current_address
Returns the current address of the voice playback.
current_left_volume
Returns the left volume value, which is the left volume modulated by the current envelope value.
current_right_volume
Returns the right volume value, which is the right volume modulated by the current envelope value.
current_envelope
Returns the current envelope value.

Discussion

This structure serves as both the input and the output of the RAD_IOPQueueAsyncSPUVoiceState function. You supply the 'in' parameters, and RAD_IOP returns the 'out' parameters.

If you don't have a callback set, then you can spin on the status field and wait for it to go greater than or equal to RAD_IOP_STATUS_COMPLETE. You then query the status for RAD_IOP_STATUS_DONE to determine if the query succeeded.

Group: The RAD_IOP SPU Hardware Voice API for the Sony PS2
Related Functions: RAD_IOPQueueAsyncSPUVoiceState, RAD_IOP_SPU_VOICE_STATE_CALLBACK
Related Basic Types: RAD_IOP_STATUS_VALUES, S32, U32


RAD_IOP_SPU_VOICE_STATE_CALLBACK

The function RAD_IOP_SPU_VOICE_STATE_CALLBACK points to a function that will be called when the async query completes.

void RAD_IOP_SPU_VOICE_STATE_CALLBACK(
  RAD_IOP_SPU_VOICE_STATE const *query_data
);

In Parameters

query_data
Specifies the pointer to the structure that you called RAD_IOPQueueAsyncSPUVoiceState with.

Discussion

This function will be called once the query is completed (at interrupt level). Be careful that the code you write in this function is interrupt-safe.

This callback will be made for success or failure, so check the status field value to determine whether the query actually succeeded.

Group: The RAD_IOP SPU Hardware Voice API for the Sony PS2
Related Functions: RAD_IOPQueueAsyncSPUVoiceState
Related Basic Types: void
Related Structures: RAD_IOP_SPU_VOICE_STATE


RAD_IOPQueueAsyncSPUGlobalState

The function RAD_IOPQueueAsyncSPUGlobalState asynchronously queries the state of the SPU cores.

S32 RAD_IOPQueueAsyncSPUGlobalState(
  RAD_IOP_SPU_GLOBAL_STATE *state_data
);

Out Parameters

state_data
Specifies the input and output parameters for the global SPU states.

Returns

Non-zero if the query was queued successfully, zero for failure.

Discussion

This function queues up a global SPU query to happen in the background.

You fill out the optional callback field (or set it to zero), and then call this function.

You can check for completion using the callback, or just poll the status field. When the status becomes RAD_IOP_STATUS_DONE, the current state fields are valid.

You can use this field to see where the current playback position is, to see whether the voice is still playing, or to check the current envelope level.

Group: The RAD_IOP SPU Hardware Voice API for the Sony PS2
Related Functions: RAD_IOPFindNonPlayingVoiceMask, RAD_IOPQueueAsyncSPUVoiceState, RAD_IOP_SPU_GLOBAL_STATE_CALLBACK
Related Basic Types: RAD_IOP_STATUS_VALUES, S32
Related Structures: RAD_IOP_SPU_GLOBAL_STATE


RAD_IOP_SPU_GLOBAL_STATE

The structure RAD_IOP_SPU_GLOBAL_STATE is a structure used with the RAD_IOPQueueAsyncSPUGlobalState function.

struct RAD_IOP_SPU_GLOBAL_STATE
{
  RAD_IOP_SPU_GLOBAL_STATE_CALLBACK callback;
  RAD_IOP_STATUS_VALUES status;
  S32 current_playing_mask[ 2 ];
  U32 current_playing_count[ 2 ];
  U32 current_dry_left_mask[ 2 ];
  U32 current_wet_right_mask[ 2 ];
  U32 current_wet_left_mask[ 2 ];
  U32 current_wet_right_mask[ 2 ];
  U32 current_end_hit_mask[ 2 ];
};

In Members

callback
Specifies a callback that should be made upon completion. If you don't want to be called back, then set this field to zero.

Out Members

status
Contains the current status of the async status.
current_playing_mask[ 2 ]
Returns the current playing/not-playing mask for core 0 in the first U32, and core 1 in the second U32.
current_playing_count[ 2 ]
Returns the current count of playing voices on core 0 in the first U32 and core 1 in the second U32.
current_dry_left_mask[ 2 ]
Returns the current on/off dry left channel mask for core 0 in the first U32, and core 1 in the second U32.
current_wet_right_mask[ 2 ]
Returns the current on/off dry right channel mask for core 0 in the first U32, and core 1 in the second U32.
current_wet_left_mask[ 2 ]
Returns the current on/off wet left channel mask for core 0 in the first U32, and core 1 in the second U32.
current_wet_right_mask[ 2 ]
Returns the on current on/off wet right channel mask for core 0 in the first U32, and core 1 in the second U32.
current_end_hit_mask[ 2 ]
Returns the low-level ENDX register mask.

Discussion

This structure serves as both the input and the output of the RAD_IOPQueueAsyncSPUGlobalState function. You supply the 'in' parameters, and RAD_IOP returns the 'out' parameters.

The current_playing_mask fields are bit masks, and the current_playing_count is simply a count of them. So, if voices 5 and 7 were playing on core 0, then current_playing_mask[ 0 ] would be "( 1 << 5 ) | ( 1 << 7 )", and current_playing_count[ 0 ] would be "2".

If you don't have a callback set, then you can spin on the status field and wait for it to go greater than or equal to RAD_IOP_STATUS_COMPLETE. You then query the status for RAD_IOP_STATUS_DONE to determine if the query succeeded.

Group: The RAD_IOP SPU Hardware Voice API for the Sony PS2
Related Functions: RAD_IOPQueueAsyncSPUGlobalState, RAD_IOP_SPU_GLOBAL_STATE_CALLBACK
Related Basic Types: RAD_IOP_STATUS_VALUES, S32, U32


RAD_IOP_SPU_GLOBAL_STATE_CALLBACK

The function RAD_IOP_SPU_GLOBAL_STATE_CALLBACK points to a function that will be called when the async query completes.

void RAD_IOP_SPU_GLOBAL_STATE_CALLBACK(
  RAD_IOP_SPU_GLOBAL_STATE const *query_data
);

In Parameters

query_data
Specifies the pointer to the structure that you called RAD_IOPQueueAsyncSPUGlobalState with.

Discussion

This function will be called once the query is completed (at interrupt level). Be careful that the code you write in this function is interrupt-safe.

This callback will be made for success or failure, so check the status field value to determine whether the query actually succeeded.

Group: The RAD_IOP SPU Hardware Voice API for the Sony PS2
Related Functions: RAD_IOPQueueAsyncSPUGlobalState
Related Basic Types: void
Related Structures: RAD_IOP_SPU_GLOBAL_STATE


RAD_IOPFindNonPlayingVoiceMask

The function RAD_IOPFindNonPlayingVoiceMask returns a bitmask that corresponds to a single non-playing voice.

S32 RAD_IOPFindNonPlayingVoiceMask(
  U32 mask
);

In Parameters

mask
Specifies a mask of playing and non-playing voices (usually returned from the RAD_IOPQueueAsyncSPUGlobalState).

Returns

Returns a bitmask of one of the non-playing voices in the input mask.

Discussion

This function is just a simple utility function.

Given a voice playing mask (where '1' bits correspond to playing voices and '0' bits indicate non-playing ones), this function will quickly return a mask indicating the first voice that isn't playing. For example, if all voices except for voice 2 were playing, then the input mask would be 0xfffffb, and this function would return 4 (i.e., 1 << 2).

Group: The RAD_IOP SPU Hardware Voice API for the Sony PS2
Related Functions: RAD_IOPQueueAsyncSPUGlobalState
Related Basic Types: S32, U32


Low-Level DOS Installation Services

Discussion

The Low-Level DOS Installation Services are used when the high-level digital and XMIDI DOS sound driver installation functions are insufficient.

Low-Level DOS Installation Services
AIL_install_DIG_driver_image | installs and initializes an MSS-compatible .DIG driver file for digital audio performance.
AIL_install_MDI_driver_image | Installs and initializes an MSS-compatible .MDI driver file for XMIDI music performance.
AIL_get_IO_environment | searches for and evaluates a DOS environment variable which contains I/O configuration data for a particular MSS driver.
AIL_read_INI | reads a standard MSS MDI.INI or DIG.INI file, parses it, and stores its contents in an application-specified AIL_INI structure.
AIL_INI | returns the contents of a MSS INI file.
AIL_install_driver | registers an MSS-compatible driver of any supported type with the MSS API, returning an AIL_DRIVER descriptor.
AIL_uninstall_driver | shuts down and unloads an MSS-compatible driver which was previously installed by AIL_install_driver above.


AIL_install_DIG_driver_image

The function AIL_install_DIG_driver_image installs and initializes an MSS-compatible .DIG driver file for digital audio performance.

HDIGDRIVER AIL_install_DIG_driver_image(
  void const * driver_image,
  U32 size,
  IO_PARMS * const *IO
);

In Parameters

driver_image
points to a memory-resident driver file image.
size
specifies the size of the driver file image in bytes.
IO
specifies a particular I/O configuration to use when initializing the driver. If *IO is NULL or if the device cannot be detected using the specified parameters, the function will attempt to auto-detect the supported device using DOS environment strings or other driver-specific techniques.

Returns

A pointer to a dynamically allocated structure of type DIG_DRIVER, which may be passed by the application to subsequent function calls involving the driver; or NULL if an error occurs.

Discussion

This is a DOS-only function.

This function is identical to AIL_install_DIG_driver_file, except that the application is responsible for loading the driver file into memory. With AIL_install_DIG_driver_file, the application specifies the driver's DOS filename, and the MSS API loads the driver itself.

As a courtesy to users, and to aid in testing and debugging, please do not embed the .DIG files in any type of proprietary library file. You can leave them on your CD-ROM, if you use the AIL_set_redist_directory function to specify their location.

This function must not be invoked from an interrupt-based callback function.

Group: Low-Level DOS Installation Services
Related Functions: AIL_get_IO_environment, AIL_install_DIG_driver_file, AIL_install_MDI_driver_image, AIL_set_redist_directory
Related Basic Types: HDIGDRIVER, MILES_PREFERENCES, U32, void const *
Related Structures: IO_PARMS


AIL_install_MDI_driver_image

The function AIL_install_MDI_driver_image Installs and initializes an MSS-compatible .MDI driver file for XMIDI music performance.

HMDIDRIVER AIL_install_MDI_driver_image(
  void const * driver_image,
  U32 size,
  IO_PARMS * const *IO
);

In Parameters

driver_image
points to a memory-resident driver file image.
size
specifies the size of the driver file image in bytes.
IO
specifies a particular I/O configuration to use when initializing the driver. If *IO is NULL or if the device cannot be detected using the specified parameters, the function will attempt to auto-detect the supported device using DOS environment strings or other driver-specific techniques.

Returns

A pointer to a dynamically allocated structure of type MDI_DRIVER, which may be passed by the application to subsequent function calls involving the driver; or NULL if an error occurs.

Discussion

This is a DOS-only function.

This function is identical to AIL_install_MDI_driver_file, except that the application is responsible for loading the driver file into memory. With AIL_install_MDI_driver_file, the application specifies the driver's DOS filename, and the MSS API loads the driver itself.

As a courtesy to users, and to aid in testing and debugging, please do not embed the .MDI files in any type of proprietary library file. You can leave them on your CD-ROM, if you use the AIL_set_redist_directory function to specify their location.

This function must not be invoked from an interrupt-based callback function.

Group: Low-Level DOS Installation Services
Related Functions: AIL_get_IO_environment, AIL_install_DIG_driver_image, AIL_install_MDI_driver_file, AIL_set_GTL_filename_prefix, AIL_set_redist_directory
Related Basic Types: HMDIDRIVER, U32, void const *
Related Structures: IO_PARMS


AIL_get_IO_environment

The function AIL_get_IO_environment searches for and evaluates a DOS environment variable which contains I/O configuration data for a particular MSS driver.

IO_PARMS * AIL_get_IO_environment(
  AIL_DRIVER * drvr
);

In Parameters

drvr
points to an AIL_DRIVER driver descriptor structure. AIL_DRIVER may be thought of as the "base class" from which high-level MSS driver types such as DIG_DRIVER and MDI_DRIVER are derived. To obtain a pointer to an AIL_DRIVER structure for a variable x of type HDIGDRIVER or HMDIDRIVER, use an expression of the form x->drvr.

Returns

A pointer to a static structure of type IO_PARMS, which contains information about a driver's I/O port configuration.

Discussion

This is a DOS-only function.

This function is called internally by the higher-level AIL_install_DIG_driver_file/AIL_install_MDI_driver_file and AIL_install_DIG_driver_image/AIL_install_MDI_driver_image functions, as part of the auto-detection process which these functions will perform if a valid IO_PARMS structure is not passed to them explicitly. Most applications, with the possible exception of installation programs, will not need to use this function. Installation programs may, if desired, call AIL_get_IO_environment to obtain the "default" values to be used in prompting the end-user for I/O information prior to accessing any hardware ports. Most Sound Blaster-equipped systems contain a BLASTER environment variable, for instance, which contains all information necessary to communicate with the card.

Under DOS, this function must not be invoked from an interrupt-based callback function.

Group: Low-Level DOS Installation Services
Related Functions: AIL_get_IO_environment, AIL_install_DIG_driver_file, AIL_install_DIG_driver_image, AIL_install_MDI_driver_file, AIL_install_MDI_driver_image, AIL_read_INI
Related Basic Types: AIL_DRIVER
Related Structures: IO_PARMS


AIL_read_INI

The function AIL_read_INI reads a standard MSS MDI.INI or DIG.INI file, parses it, and stores its contents in an application-specified AIL_INI structure.

S32 AIL_read_INI(
  AIL_INI *INI,
  char const * filename
);

In Parameters

filename
specifies the filename of the .INI file to read. The SETSOUND driver configuration program creates .INI files with the standard names DIG.INI and MDI.INI.

Out Parameters

INI
points to an instance of a structure of type AIL_INI, which will be filled with the parsed contents of the MDI.INI or DIG.INI file.

Returns

0 if the .INI file was not present or could not be parsed; otherwise 1.

Discussion

This is a DOS-only function.

This function is used internally by the AIL_install_DIG_INI and AIL_install_MDI_INI functions to parse the driver configuration files written by the SETSOUND driver configuration utility. Most applications can use these two functions to install the selected drivers automatically, rather than calling AIL_read_INI directly.

An example of a valid .INI file, as written by the SETSOUND utility, follows:

;
;RAD Game Tools: Miles Sound System V6.0a of 11-Nov-99
;
DEVICE Creative Labs Sound Blaster(TM) or 100% compatible
DRIVER SBLASTER.DIG
IO_ADDR 220h
IRQ 5
DMA_8_BIT 1
DMA_16_BIT -1

Group: Low-Level DOS Installation Services
Related Sections: SETSOUND - MSS Sound Configuration Utility
Related Functions: AIL_get_IO_environment, AIL_install_DIG_INI, AIL_install_MDI_INI, AIL_read_INI
Related Basic Types: S32, char const *
Related Structures: AIL_INI


AIL_INI

The structure AIL_INI returns the contents of a MSS INI file.

struct AIL_INI
{
  char const * device_name;
  char const * driver_name;
  IO_PARMS * IO;
};

In Members

device_name
Specifies the device name.
driver_name
Specifies the driver filename.
IO
Specifies the I/O parameters for the driver.

Group: Low-Level DOS Installation Services
Related Functions: AIL_read_INI
Related Basic Types: char const *
Related Structures: IO_PARMS


AIL_install_driver

The function AIL_install_driver registers an MSS-compatible driver of any supported type with the MSS API, returning an AIL_DRIVER descriptor.

AIL_DRIVER * AIL_install_driver(
  U8 const * driver_image,
  U32 n_bytes
);

In Parameters

driver_image
points to a memory-resident image of the driver to be installed.
n_bytes
is the size of the driver image in bytes.

Returns

A pointer to a dynamically allocated structure of type AIL_DRIVER driver. AIL_DRIVER may be thought of as the "base class" from which high-level MSS driver types such as DIG_DRIVER and MDI_DRIVER are derived, or NULL if any errors occur. For example, a pointer to an AIL_DRIVER structure for a variable x of type HDIGDRIVER or HMDIDRIVER may be obtained by using an expression of the form x->drvr.

Discussion

This is a DOS-only function.

This function must not be invoked from an interrupt-based callback function.

Group: Low-Level DOS Installation Services
Related Functions: AIL_uninstall_driver
Related Basic Types: AIL_DRIVER, U32, U8


AIL_uninstall_driver

The function AIL_uninstall_driver shuts down and unloads an MSS-compatible driver which was previously installed by AIL_install_driver above.

void AIL_uninstall_driver(
  AIL_DRIVER * drvr
);

In Parameters

drvr
points to an AIL_DRIVER driver descriptor structure. AIL_DRIVER may be thought of as the "base class" from which high-level MSS driver types such as DIG_DRIVER and MDI_DRIVER are derived. To obtain a pointer to an AIL_DRIVER structure for a variable x of type HDIGDRIVER or HMDIDRIVER, use an expression of the form x->drvr.

Discussion

This is a DOS-only function.

AIL_uninstall_driver is intended mainly for use by specific driver uninstallation functions, such as AIL_close_digital_driver/AIL_close_XMIDI_driver, rather than by application programs. Most applications will not need to call AIL_uninstall_driver directly.

Drivers must be uninstalled in the opposite order of their installation (last-in, first-out).

This function must not be invoked from an interrupt-based callback function.

Group: Low-Level DOS Installation Services
Related Functions: AIL_close_XMIDI_driver, AIL_close_digital_driver, AIL_install_driver, AIL_uninstall_driver
Related Basic Types: AIL_DRIVER, void


Low-Level DOS Support Services

Discussion

The Low-Level DOS Support Services are rarely necessary at the application level - they provide interrupt and stack handling services.

Low-Level DOS Support Services
AIL_set_real_vect | installs a real-mode handler real_ptr for interrupt vectnum.
AIL_set_USE16_ISR | creates a 16-bit protected-mode interrupt handler for interrupt vectnum, mapped to an existing bimodal interrupt handler in real-mode memory.
AIL_disable_interrupts | disables hardware interrupts (IRQs).
AIL_restore_interrupts | restores the hardware interrupt state effective prior to the last call to AIL_disable_interrupts (above).
AIL_switch_stack | allows a C or C++ module to change to a different stack whose size and location may be chosen by the programmer.
AIL_restore_stack | returns to the default stack which was in use prior to the last call to AIL_switch_stack.
AIL_get_real_vect | obtains the address of the current real-mode handler for interrupt vectnum.
AIL_call_driver | performs a call to an MSS-compatible sound driver in real-mode memory.
VDI_CALL | specifies the registers passed or returned from a real-mode driver call.


AIL_set_real_vect

The function AIL_set_real_vect installs a real-mode handler real_ptr for interrupt vectnum.

void AIL_set_real_vect(
  U32 vectnum,
  REALFAR real_ptr
);

In Parameters

vectnum
specifies the interrupt vector number.
real_ptr
specifies the address of the new real-mode interrupt service routine (ISR).

Discussion

This is a DOS-only function.

This function is used internally by the MSS system. Most applications will not need to use AIL_set_real_vect.

Group: Low-Level DOS Support Services
Related Functions: AIL_get_real_vect, AIL_set_USE16_ISR, AIL_set_real_vect
Related Basic Types: REALFAR, U32, void


AIL_set_USE16_ISR

The function AIL_set_USE16_ISR creates a 16-bit protected-mode interrupt handler for interrupt vectnum, mapped to an existing bimodal interrupt handler in real-mode memory.

U32 AIL_set_USE16_ISR(
  U32 vectnum,
  REALFAR real_base,
  U32 ISR_offset
);

In Parameters

vectnum
specifies the interrupt vector number.
real_base
specifies the paragraph-aligned real-mode (segment:offset) address of the module containing the bimodal interrupt handler.
ISR_offset
specifies the offset in bytes from real_base of the bimodal interrupt handler.

Returns

The USE16 code selector created and mapped to real_base.

Discussion

This is a DOS-only function.

This function is used internally by the MSS system, and may not be available under all DOS extenders or MSS API versions. Most applications will not need to use AIL_set_USE16_ISR.

This function must not be invoked from an interrupt-based callback function.

Group: Low-Level DOS Support Services
Related Functions: AIL_set_USE16_ISR, AIL_set_real_vect
Related Basic Types: REALFAR, U32


AIL_disable_interrupts

The function AIL_disable_interrupts disables hardware interrupts (IRQs).

U32 AIL_disable_interrupts();

Returns

A special value which may be passed to AIL_restore_interrupts to restore the previous interrupt flag state. This value represents the CPU flags word, not a simple Boolean interrupt state value.

Discussion

This is a DOS-only function.

This function is used internally by the MSS system, and provides a standardized interrupt-disabling function which is independent of the runtime environment in use. Most applications will not need to use AIL_disable_interrupts, as long as they use the MSS API functions to manipulate sound effect and sequence data. It is important to preserve the returned flags value for later use with AIL_restore_interrupts (below), when interrupts no longer need to be disabled.

Disabling interrupts for more than a few milliseconds may cause dropouts and other undesirable effects with digitized sound output, and may also result in music tempo slowdowns.

Group: Low-Level DOS Support Services
Related Functions: AIL_disable_interrupts, AIL_restore_interrupts
Related Basic Types: U32


AIL_restore_interrupts

The function AIL_restore_interrupts restores the hardware interrupt state effective prior to the last call to AIL_disable_interrupts (above).

U32 AIL_restore_interrupts(
  U32 FD_register
);

In Parameters

FD_register
contains the returned value from the last call to AIL_disable_interrupts made by the application.

Discussion

This is a DOS-only function.

AIL_restore_interrupts restores the hardware interrupt state which was in effect prior to the last call to AIL_disable_interrupts. Each call to AIL_disable_interrupts must be matched by one, and only one, subsequent call to AIL_restore_interrupts.

This function is used internally by the MSS system. Most applications will not need to use AIL_restore_interrupts, as long as they use the MSS API functions to manipulate sound effect and sequence data.

Group: Low-Level DOS Support Services
Related Functions: AIL_disable_interrupts, AIL_restore_interrupts
Related Basic Types: U32


AIL_switch_stack

The function AIL_switch_stack allows a C or C++ module to change to a different stack whose size and location may be chosen by the programmer.

void AIL_switch_stack(
  void *stack,
  U32 size,
  U32 * SS,
  void * * ESP,
  void * * EBP
);

In Parameters

size
specifies the size in bytes of the new stack.
SS
points to a variable of type U32 which will be used later by AIL_restore_stack to return to the default application stack.
ESP
points to a variable of type void * which will be used later by AIL_restore_stack to return to the default application stack.
EBP
points to a variable of type void * which will be used later by AIL_restore_stack to return to the default application stack.

Out Parameters

stack
points to a statically declared or globally allocated area of memory suitable for use as a stack. This area must reside within the application's normal data segment, and should be a multiple of 4 bytes in size.

Discussion

This is a DOS-only function.

Auto variables may be used from within a function that calls AIL_switch_stack, but their values are not copied from the default stack to the new stack by this function. Note that some or all of a function's formal arguments are actually considered auto variables, implying that argument values should be copied to static variables before calling AIL_switch_stack. Compiler register optimizations may mask problems resulting from failure to preserve function arguments and/or auto variable contents; however, seemingly unrelated failures may occur when minor changes are made to the code at a later date.

Any Watcom C/C++ modules which contain calls to AIL_switch_stack must be compiled with the -of+ option, to force generation of traceable stack frames. Otherwise, EBP may be assigned for use as a register variable prior to the AIL_switch_stack call, resulting in improper stack frame creation.

Prior to exiting, a function which has called AIL_switch_stack must return to the normal stack by means of a call to AIL_restore_stack.

This function is used internally by the MSS system. Most applications will not need to use AIL_switch_stack, unless large interrupt handlers with extensive stack usage are implemented in C, and/or preemptive multi-threaded timer services are enabled. (By default, preemptive timer services are disabled, and the internal timer dispatcher switches to its own 2kb stack before calling any timer callback functions.) Misuse of AIL_switch_stack can cause obscure, difficult-to-trace bugs; it is not recommended that this function be used by programmers unfamiliar with C's stack frame architecture.

Group: Low-Level DOS Support Services
Related Sections: Callbacks under DOS
Related Functions: AIL_restore_stack, AIL_switch_stack
Related Basic Types: U32, void


AIL_restore_stack

The function AIL_restore_stack returns to the default stack which was in use prior to the last call to AIL_switch_stack.

void AIL_restore_stack(
  U32 SS,
  void * ESP,
  void * EBP
);

In Parameters

SS
contains a variable of type U32 which was written by AIL_switch_stack.
ESP
contains a variable of type void * which was written by AIL_switch_stack.
EBP
contains a variable of type void * which was written by AIL_switch_stack.

Discussion

This is a DOS-only function.

Refer to AIL_switch_stack for details on switching stacks from within a C function.

This function is used internally by the MSS system. Most applications will not need to use AIL_switch_stack, unless large interrupt handlers with extensive stack usage are implemented in C, and/or preemptive multi-threaded timer services are enabled.

Group: Low-Level DOS Support Services
Related Functions: AIL_switch_stack
Related Basic Types: U32, void, void *


AIL_get_real_vect

The function AIL_get_real_vect obtains the address of the current real-mode handler for interrupt vectnum.

REALFAR AIL_get_real_vect(
  U32 vectnum
);

In Parameters

vectnum
specifies the interrupt vector number whose handler address is to be returned.

Returns

The address of the real-mode interrupt service routine (ISR) which is associated with the specified interrupt. This handler will be called when the specified interrupt occurs while the system is performing a real-mode task.

Discussion

This is a DOS-only function.

This function is used internally by the MSS system. Most applications will not need to use AIL_get_real_vect.

Group: Low-Level DOS Support Services
Related Functions: AIL_get_real_vect, AIL_set_real_vect
Related Basic Types: REALFAR, U32


AIL_call_driver

The function AIL_call_driver performs a call to an MSS-compatible sound driver in real-mode memory.

S32 AIL_call_driver(
  AIL_DRIVER * drvr,
  S32 fn,
  VDI_CALL * const *in,
  VDI_CALL *out
);

In Parameters

drvr
points to an AIL_DRIVER driver descriptor structure. AIL_DRIVER may be thought of as the "base class" from which high-level MSS driver types such as DIG_DRIVER and MDI_DRIVER are derived. To obtain a pointer to an AIL_DRIVER structure for a variable x of type HDIGDRIVER or HMDIDRIVER, use an expression of the form x->drvr.
fn
gives the driver's function number to invoke. Since applications should use AIL_call_driver only to invoke a Vendor-Specific Extensions (VSE) function for a particular driver, fn should normally equal the DIG_VSE or MDI_VSE labels.
in
may be set to NULL, or may point to a structure of type VDI_CALL, which contains all values to be passed to the driver function handler. To make a VSE call, the VDI_CALL structure's CX member should be set to correspond to the VSE feature identifier for the requested operation. Refer to the current MSS DDK Interface chapter for a list of assigned VSE calls and required register values.

Out Parameters

out
may be set to NULL, or may point to a structure of type VDI_CALL, into which will be stored all values returned from the driver function handler. Refer to the current MSS DDK Interface chapter for a list of assigned VSE calls and their returned values, if any.

Returns

The AX register as returned from the driver function handler. This is equal to out->AX, sign-extended from WORD (16 bits) to S32 (32 bits). Many driver functions use AX to return codes for success (> 0) or failure (0). A returned value of -1 normally indicates that the requested function is not supported by the driver.

Discussion

This is a DOS-only function.

This function is used internally by the MSS system. Applications should use AIL_call_driver only to invoke Vendor-Specific Extensions (VSE) functions for particular drivers, where desired. Applications which do not make VSE calls will not need to use AIL_call_driver at all.

Group: Low-Level DOS Support Services
Related Functions: AIL_call_driver
Related Basic Types: AIL_DRIVER, S32
Related Structures: VDI_CALL


VDI_CALL

The structure VDI_CALL specifies the registers passed or returned from a real-mode driver call.

struct VDI_CALL
{
  S16 AX;
  S16 BX;
  S16 CX;
  S16 DX;
  S16 SI;
  S16 DI;
};

In Members

AX
Specifies the AX register.
BX
Specifies the BX register.
CX
Specifies the CX register.
DX
Specifies the DX register.
SI
Specifies the SI register.
DI
Specifies the DI register.

Group: Low-Level DOS Support Services
Related Functions: AIL_call_driver
Related Basic Types: S16


Preferences

Discussion

Preferences help keep the MSS API easy for beginners (and impatient experts) to learn and use, while permitting a high degree of control over MSS's configuration and operation as specific needs arise.

The AIL_set_preference function allows the application to influence MSS's default behavior in a number of different situations, by specifying a preference name and its corresponding preference value. As a rule, calls to AIL_set_preference have no immediate effect. Instead, the function simply writes the application's preference value to a global preference array which is accessible to all of MSS's internal modules and functions. Subsequently, the new preference value is used during execution of all MSS functions which depend on it for guidance.

Preferences
AIL_set_preference | controls certain internal parameters used by the MSS system.
AIL_get_preference | queries the current MSS internal parameters.
MILES_PREFERENCES | describes the Miles Sound System Preferences.


MILES_PREFERENCES

The basic type MILES_PREFERENCES describes the Miles Sound System Preferences.

Fundamental Values

Value Description
DIG_MAX_PREDELAY_MS This preference controls the maximum predelay you can use when applying 2D digital reverb. The longer the predelay, the more memory is required (4 bytes * the output frequency).

This preference value must be changed before calling AIL_open_digital_driver.

Environment: DOS/Win32/Win64/MacOS. Units: Milliseconds.

Default Value: 500 (ms).
DIG_ENABLE_RESAMPLE_FILTER This preference determines the whether the MSS mixer should perform sound filtering when upsampling or downsampling a sound effect. This is a very low overhead operation, so you should generally just leave this preference turned on.

Environment: DOS/Win32/Win64/MacOS.

Units: Boolean ( YES / NO ).

Default Value: YES.
DIG_MIXER_CHANNELS DIG_MIXER_CHANNELS determines the number of HSAMPLE sample handles which may be allocated with the AIL_allocate_sample_handle function. The AIL_create_wave_synthesizer function also allocates a number of sample handles which is determined by its polyphony parameter value. At any moment in time, each instance of a playing digital sound effect requires one HSAMPLE handle.

The value of this preference may be increased if desired, but system performance may be degraded if too many samples are played simultaneously. The practical limit depends on the hardware DMA data rate in use and the system's capabilities. For example, it may be possible to play hundreds of samples simultaneously with an 11- kHz 8-bit mono driver configuration running on a high-end PC system, while only one or two simultaneous samples should be played on a 386-class system whose sound driver is configured for 16-bit stereo 44 Khz DMA transfers. Because scaling source sample data to a given hardware configuration consumes a relatively small amount of CPU time, the hardware (DMA) data rate being used affects system performance to a much greater extent than does the playback rate, number of channels, and word size of the source sample data.

Any changes made to the DIG_MIXER_CHANNELS preference value must be made prior to installing the digital driver in question.

Environment: DOS/Win32/Win64/MacOS.

Units: # of simultaneous digital sound effects permitted.

Default Value: 64.
DIG_RESAMPLING_TOLERANCE When the playback rate of a sample passed to MSS differs from the hardware sample rate in use (as defined by the DIG_HARDWARE_SAMPLE_RATE preference), the data must be resampled to play at its normal speed and pitch. This resampling process requires a minute amount of CPU time beyond that required to play data which does not need to be resampled. By setting the DIG_RESAMPLING_TOLERANCE preference prior to initializing a digital audio driver, the application can specify that no resampling is to occur if the source sample data does not vary from the hardware data rate by more than a certain percentage.

Environment: DOS/Win32/Win64/MacOS.

Units: Tolerance percentage expressed as (n / 65536).

Default Value: 0% (0).
AIL_TIMERS This preference value determines how many HTIMER handles may be allocated with AIL_register_timer. Any changes to this preference value must be made immediately after AIL_startup is called.

AIL_TIMERS should not normally need to be changed by the application, except in cases where more than 16 timer service clients, including XMIDI drivers and application callback functions, must be serviced.

Environment: DOS/Win32/Win64/MacOS.

Units: Number of timers which can be allocated with AIL_register_timer.

Default Value: 16.
AIL_CPU_AFFINITY On some platforms (currently limited to Xbox 360), this preference can be used to bind the Miles background thread to a specified CPU core. This background thread is responsible for executing all of Miles's audio processing and mixing code on the Xbox 360, including any user-registered timers and other callback functions. Any changes to this preference value must be made immediately after AIL_startup is called.

Environment: Xbox 360.

Units: CPU index passed to the Microsoft XSetThreadProcessor API when Miles creates its background thread.

Default Value: 2.
MDI_SERVICE_RATE When an XMIDI music driver is loaded, the MSS API arranges to receive background timer interrupt service at a rate governed by the MDI_SERVICE_RATE preference. The timer routine is responsible for background playback of XMIDI sequences.

This preference also controls the rate at which sequences are converted with the AIL_MIDI_to_XMI function.

Any changes to the MDI_SERVICE_RATE preference must be made prior to XMIDI driver installation.

Environment: DOS/Win32/Win64/MacOS.

Units: Frequency in hertz (interrupts per second).

Default Value: 120.
MDI_SEQUENCES MDI_SEQUENCES determines the number of HSEQUENCE sequence handles which may be allocated with the AIL_allocate_sequence_handle function. At any moment in time, each instance of a playing XMIDI sequence requires one HSEQUENCE handle.

The value of this preference may be increased if desired, but the set of 16 physical MIDI channels may limit the number of sequences which can be played simultaneously. Most applications should not need to increase the MDI_SEQUENCES limit.

Any changes made to the MDI_SEQUENCES preference value must be made prior to installing the XMIDI driver.

Environment: DOS/Win32/Win64/MacOS.

Units: # of simultaneously playing XMIDI sequences permissible.

Default Value: 8.
MDI_DEFAULT_VOLUME The MDI_DEFAULT_VOLUME preference value determines the default volume-scaling factor assigned to all channels of all sequences by the AIL_init_sequence function.

By default, the individual channel volume controller values in XMIDI sequences are not scaled by MSS.

This preference value does not ordinarily need to be changed, since the volume-scaling factor for any XMIDI sequence may be altered at any time by use of the AIL_set_sequence_volume function.

Environment: DOS/Win32/Win64/MacOS.

Units: MIDI-compatible volume controller units (0-127).

Default Value: 127.
MDI_QUANT_ADVANCE This preference value allows the AIL_sequence_position function to report the XMIDI beat and measure count for a given sequence in advance of their actual occurrences.

For more information about this preference, refer to the description of the AIL_sequence_position function.

Environment: DOS/Win32/Win64/MacOS.

Units: XMIDI quantization intervals (0...n).

Default Value: 1.
MDI_ALLOW_LOOP_BRANCHING When an AIL_branch_index function call is issued, or an XMIDI Sequence Branch controller (109) is encountered in a playing XMIDI sequence, any XMIDI For...Next/Break loops defined with controllers 116 and 117 are canceled in the sequence in question. This is done to prevent errors caused by branches into or out of loops. In cases where branching within a looped portion of a sequence is required, and the musician and programmer are willing to ensure that branches across loop boundaries never occur, the MDI_ALLOW_LOOP_BRANCHING preference may be set to YES to avoid loss of loop information when a branch is taken.

Environment: DOS/Win32/Win64/MacOS.

Units: Boolean (YES / NO).

Default Value: NO.
MDI_DEFAULT_BENDER_RANGE One important feature introduced with the MSS version 3.00 release was the official support of the Roland Sound Canvas's de facto General MIDI implementation as the baseline standard for XMIDI performance parameters, replacing the obsolete Roland MT-32 standard under which the older libraries were designed. The default pitch bender range under the MT-32 MIDI standard was plus or minus 12 notes, or semitones, but the Sound Canvas established a new default value of two semitones.

It is possible to adjust the pitch bend range in a MIDI channel at performance time by setting MIDI Registered Parameter Number 0's data MSB to the new bender range value. However, existing sequences composed under MSS 2.X are not likely to contain RPN 0 controller values, since the older Roland-derived MIDI standard did not recognize RPN events. It may be desirable to set the MDI_DEFAULT_BENDER_RANGE preference to 12 when porting MSS 2.X applications to the current MSS, if adding RPN controllers to all of the application's MIDI sequences is impractical. Changes to MDI_DEFAULT_BENDER_RANGE take effect during XMIDI driver initialization.

This function may not be supported by all Windows midiOut drivers.

Environment: DOS/Win32/Win64/MacOS.

Units: MIDI semitones (discrete note increments).

Default Value: 2.
MDI_SYSEX_BUFFER_SIZE This preference value determines the size of the largest System Exclusive message which can be transmitted from an XMIDI file or from the AIL_send_sysex_message function.

MDI_SYSEX_BUFFER_SIZE should not normally need to be changed by the application.

Environment: Win32/Win64/MacOS.

Units: Bytes.

Default Value: 512.
MDI_DOUBLE_NOTE_OFF This preference value is present to help you work around a nasty bug in the Sound Blaster 16 General MIDI daughter cards. Occasionally the interface portion of the Sound Blaster 16 can drop General MIDI commands when there is busy MIDI traffic. Most MIDI commands can be dropped without a problem, but if a "Note-Off" is missed, then your MIDI notes can "stick".

When you turn this preference on, then MSS will send all Note-Off commands to the MIDI card twice (creating less of a chance that the Note-Off will be missed). This preference will nearly double the MIDI traffic, so use it if you have problems with stuck notes on Sound Blaster 16 daughter cards with very complicated MIDI songs.

Environment: DOS/Win32/Win64/MacOS.

Units: Boolean (YES / NO).

Default Value: NO.
DLS_TIMEBASE Governs the rate at which the DLS software synthesizer receives periodic timer service from the system. Lower rates may yield slightly better CPU performance in some cases; higher rates yield less "quantization" of MIDI traffic. There is no benefit in setting the DLS_TIMEBASE preference value higher than the MDI_SERVICE_RATE preference value, as MIDI events cannot be interpreted faster than they arrive from the synthesizer driver.

This preference value must be altered before calling AIL_DLS_open.

Environment: DOS/Win32/Win64/MacOS.

Units: Frequency in hertz (interrupts per second).

Default Value: 120.
DLS_VOICE_LIMIT Sets the maximum number of simultaneous DLS synthesizer voices available. The default value of 24 complies with MMA guidelines, and is sufficient for most applications.

This preference value must be altered before calling AIL_DLS_open.

Environment: DOS/Win32/Win64/MacOS.

Units: Number of simultaneous DLS voices permissible.

Default Value: 24.
DLS_BANK_SELECT_ALIAS By default, the XMIDI Patch Bank Select controller (114) is not used as an alias for the General MIDI bank select controllers (0 and 32). The XMIDI Patch Bank Select controller has been de-emphasized by RAD Game Tools as of the MSS 4.0 release, and should not be used for future compositions. Legacy compositions which use XMIDI Patch Bank Select may be made DLS-compatible by setting this preference to YES.

If this preference is set to YES, the General MIDI Bank MSB value for a given channel (controller 0) will be set to 0 whenever a Patch Bank Select controller is encountered in that channel.

This preference value may be altered on demand at runtime.

Environment: DOS/Win32/Win64/MacOS.

Units: Boolean (YES / NO).

Default Value: NO.
DLS_VOLUME_BOOST DLS-synthesized instruments contain numerous level scalars and articulators, all of which, when interpreted by the synthesizer, result in a reduction of overall output volume compared to the levels at which the wave data were originally recorded. By default, the synthesizer output level is boosted by 10 dB in the final mixing stage, to help keep DLS-synthesized music from being drowned out by digital sound effects and other sources of sound in an application.

This preference value may be altered on demand at runtime.

Environment: DOS/Win32/Win64/MacOS.

Units: Decibels.

Default Value: 10.
DLS_GM_PASSTHROUGH By default, MIDI data which is not interpreted by the DLS software synthesizer is passed on to the default MIDI hardware synthesizer driver. Setting this preference to NO causes uninterpreted data to be discarded. Many applications which deal with "legacy" sequence data may benefit from setting this preference to NO, to avoid unwanted or inappropriate output from the MIDI hardware synthesizer in response to events in tracks which are not properly configured with bank- and/or patch-change messages.

This preference value may be altered on demand at runtime.

Environment: DOS/Win32/Win64/MacOS.

Units: Boolean (YES / NO).

Default Value: YES.
AIL_ENABLE_MMX_SUPPORT By default, Intel MMX support is enabled to provide a CPU performance increase. Most applications should not need to alter this preference value.

This preference value may be altered on demand at runtime.

Environment: DOS/Win32/Win64.

Units: Boolean (YES / NO).

Default Value: YES.
DIG_USE_WAVEOUT This preference is used under Win32 and Win64 if the AIL_OPEN_DIGITAL_FORCE_PREFERENCE flag is used with AIL_open_digital_driver. It determines whether MSS will use DirectSound or the low-level Windows multimedia extensions (MME).

By default, MSS tries to load DirectSound and only falls back to waveOut if DirectSound fails to load or if DirectSound is using emulation mode. This preference allows you to control specifically which technology Miles uses.

Environment: Win32/Win64.

Units: Boolean ( YES / NO ).

Default Value: NO.
DIG_PREFERRED_WO_DEVICE When the Win32 or Win64 version uses waveOut for output, this preference determines the waveOut device ID it opens.

Environment: Win32/Win64.

Units: A DWORD device ID.

Default Value: WAVE_MAPPER.
DIG_PREFERRED_DS_DEVICE When the Win32 or Win64 version uses DirectSound for output, this preference determines the LPGUID it passes to DirectSoundCreate.

Environment: Win32/Win64.

Units: A pointer to a DirectSound device GUID.

Default Value: NULL.
DIG_LEVEL_RAMP_SAMPLES This preference value determines the number of samples in each software-mixing buffer over which sample volume level changes (including 3D attenuation) take effect. Smaller values may exacerbate "zipper noise" under some conditions, while larger values take (slightly) more CPU time. The default value of 128 represents a good performance-versus-quality compromise for most applications.

Environment: All software-mixed platforms.

Units: An integer number of samples.

Default value: 128.
DIG_ENCODE_QUALITY_PERCENT This preference value provides a quality "hint" to any real-time encoder modules installed. It can range from 0 (lowest quality, least resource usage) to 100 (highest quality, most resource usage). Currently only the DTS encoder in the Sony PS2 version of Miles uses this preference. The default value of 50% represents a good performance-versus-quality compromise for most applications.

Environment: The Sony PS2's DTS encoder is currently the only platform that supports this preference.

Units: An integer percentage from 0 to 100.

Default value: 50.
DIG_OUTPUT_BUFFER_SIZE This preference value determines how large the output buffers are allocated by AIL_open_digital_driver under Windows in waveOut mode or MacOS. See AIL_open_digital_driver for details.

DIG_OUTPUT_BUFFER_SIZE should not normally need to be changed by the application, except in cases where extremely long periods of time can elapse without yielding to other tasks or calling AIL_serve.

Environment: Win32/Win64 with waveOut

Units: Bytes.

Default Value: 49,152 (48K).
AIL_MM_PERIOD This preference value determines the shortest possible timer period which may be requested with AIL_set_timer_period, AIL_set_timer_frequency, or AIL_set_timer_divisor.

AIL_MM_PERIOD should not normally need to be changed by the application, except in cases where background timer services at rates faster than 200 Hz are required.

Environment: Win32/Win64 and MacOS.

Units: Milliseconds.

Default Value: 5 (200 Hz).
AIL_MUTEX_PROTECTION Under Win32, this preference value determines whether MSS will lock calls from different threads with a system mutex. This is an alternate method to the AIL_LOCK_PROTECTION preference. If you turn on AIL_LOCK_PROTECTION, then you need to turn off AIL_MUTEX_PROTECTION, unless your main thread must continue to execute and you specifically protect against MSS being called re-entrantly.

You will probably never need to use this preference.

Environment: Win32/Win64/MacOS.

Units: Boolean (YES / NO).

Default Value: NO.
AIL_LOCK_PROTECTION Under Win32, this preference value determines whether MSS will lock the foreground thread while executing its callbacks. This is an alternate method to the AIL_MUTEX_PROTECTION preference. If you turn off AIL_MUTEX_PROTECTION, then you need to turn on AIL_LOCK_PROTECTION, unless your main thread must continue to execute and you specifically protect against MSS being called re-entrantly.

You will probably never need to use this preference.

Environment: Win32/Win64.

Units: Boolean (YES / NO).

Default Value: NO.
DIG_DS_USE_PRIMARY This preference determines the whether the MSS mixer should mix into a DirectSound secondary buffer, or whether it should mix directly into the primary sound buffer. The primary sound buffer is the very fastest method, but not all sound cards are compatible with primary buffer use. Using the primary buffer also prevents 3D providers and Smacker from playing their output.

Environment: Win32/Win64 only.

Units: Boolean ( YES / NO ).

Default Value: NO.
DIG_DS_FRAGMENT_SIZE This preference determines the big each Miles mixer fragment is.

On Win32, this preference and DIG_DS_MIX_FRAGMENT_COUNT control how far ahead the MSS mixer will mix when replacing the DirectSound mixer. Decreasing this value may lower latency, but can cause skipping problems on some sound cards.

On original Xbox, fragments are only used the audio is compressed with IMA ADCPM, Ogg Vorbis, or MP3 compression, or you are streaming the audio. These fragments are used as the DirectSound looping buffers. By default, there are 32 of these fragments available per HDIGDRIVER, but you can increase this with the DIG_DS_FRAGMENT_CNT preference.

Environment: Win32/Win64 and Xbox.

Units: Milliseconds.

Default Value: 8 on Win32, 12 on Xbox.
DIG_DS_FRAGMENT_CNT On Win32, this preference determines the maximum buffer fragments that the MSS mixer uses when it replaces the DirectSound mixer. This preference doesn't have any effect on latency - it just controls the maximum value that the DIG_DS_MIX_FRAGMENT_CNT can be set to.

On Xbox, this preference controls how many fragment buffers that are allocated to play IMA ADPCM, MP3, Ogg Vorbis, or streaming audio data per HDIGDRIVER.

Environment: Win32/Win64 and Xbox.

Units: Buffer fragments.

Default Value: 96 on Win32, 32 on Xbox.
DIG_DS_MIX_FRAGMENT_CNT This preference determines the number of buffer fragments that the MSS mixer mixes ahead when it replaces the DirectSound mixer. This preference multiplied by the DIG_DS_FRAGMENT_SIZE determines the current digital latency.

You can change this preference at runtime, so if you are getting skipping during a CPU intensive operation, you can bump up this preference, call AIL_serve to fill the digital buffers, run the CPU intensive operation, and then set this preference back to its default. This will eliminate virtually all skipping problems.

This value must be less than DIG_DS_FRAGMENT_CNT.

Environment: Win32/Win64 only.

Units: Buffer fragments.

Default Value: 8.
DIG_SM_FRAGMENT_SIZE This preference determines the big each Miles mixer fragment is. Together with the DIG_SM_MIX_FRAGMENT_COUNT controls how far ahead the MSS mixer will mix when replacing the Sound Manager mixer. Decreasing this value may lower latency, but can cause skipping problems on some sound cards.

You should never need to change this preference.

Environment: MacOS only.

Units: Milliseconds.

Default Value: 20.
DIG_SM_FRAGMENT_CNT This preference determines the maximum buffer fragments that the MSS mixer uses when it replaces the Sound Manager mixer. This preference doesn't have any effect on latency - it just controls the maximum value that the DIG_SM_MIX_FRAGMENT_CNT can be set to.

You should never need to change this preference.

Environment: MacOS only.

Units: Buffer fragments.

Default Value: 16.
DIG_SM_MIX_FRAGMENT_CNT This preference determines the number of buffer fragments that the MSS mixer mixes ahead when it replaces the Sound Manager mixer. This preference multiplied by the DIG_SM_FRAGMENT_SIZE determines the current digital latency.

You can change this preference at runtime, so if you are getting skipping during a CPU intensive operation, you can bump up this preference, call AIL_serve to fill the digital buffers, run the CPU intensive operation, and then set this preference back to its default. This will eliminate virtually all skipping problems.

This value must be less than DIG_SM_FRAGMENT_CNT.

Environment: MacOS only.

Units: Buffer fragments.

Default Value: 2.
DIG_SERVICE_RATE Under DOS, when a digital audio driver is loaded, the MSS API arranges to receive background timer interrupt service at a rate governed by the DIG_SERVICE_RATE preference. The timer routine is responsible for polling the driver's low-level buffer status to determine which, if either, of the two half-buffers is ready to be filled with the next block of output audio data. In general, to ensure that MSS has enough time to prepare the next audio data block for the driver, DIG_SERVICE_RATE should be set to a frequency which is substantially faster than the driver's half-buffer playback period. As an example, consider a hardware driver which is configured to play 16-bit audio at 20,000 Hz with a pair of 1,000-byte half-buffers. The driver's data rate is 40,000 bytes per second, implying a half-buffer playback frequency of 40,000 / 1,000, or 40 Hz. (The half-buffer playback frequency is referred to as the driver's DMA latency, and can be controlled by the use of the DIG_LATENCY preference described below.) For reliable performance in this example, DIG_SERVICE_RATE should be set to a value which is greater than 40 by a comfortable margin - at least a factor of two, or 80, would be appropriate here.

DIG_SERVICE_RATE must be set prior to calling the AIL_install_DIG_driver_file or AIL_install_DIG_driver_image function.

The default DIG_SERVICE_RATE value of 200 Hz has been chosen as a conservative compromise between CPU overhead and audio reliability with most applications. This value should be increased only when extremely low DMA latencies are specified by use of the DIG_LATENCY preference, or if very brief fragments of audio seem to be "repeated" unnaturally.

Environment: DOS only.

Units: Frequency in hertz (interrupts per second).

Default Value: 200.
DIG_HARDWARE_SAMPLE_RATE Under DOS, this preference governs the actual DMA or simulated-DMA transfer rate used by digital audio drivers. When a driver is loaded by the application, MSS must choose one of three sample rates supported by the driver, and initialize the driver for DMA or simulated-DMA playback at that sample rate. MSS's choice of sample rates is based on the DIG_HARDWARE_SAMPLE_RATE value. The three sample rates permitted by the driver represent the minimum, nominal, and maximum values supported by the hardware device for which the driver was developed. For example, the minimum, nominal, and maximum hardware sample rate values for SBLASTER.DIG are 4000, 11111, and 22222 Hz, respectively; while the values supported by SB16.DIG are 11025, 22050, and 44100 Hz, respectively. Of course, the application may specify any desired sample rate for playback of its audio data; it is MSS's responsibility to resample the application's audio data to conform to the driver's hardware playback rate. (See the description of the AIL_set_sample_playback_rate function for more information about oversampling and undersampling, and their potential effects on audio quality).

By default, the nominal sample rate (NOM_VAL) value is selected when initializing each digital audio driver. Prior to driver initialization with the AIL_install_DIG_driver_file or AIL_install_DIG_driver_image function, this preference may be set to the MIN_VAL, NOM_VAL, or MAX_VAL. Alternatively, an explicit sample rate value may be supplied to the AIL_set_preference function for the DIG_HARDWARE_SAMPLE_RATE preference. In this case, MSS will select the closest match from the three sample rate choices offered by the driver. Use of MIN_VAL for this preference is not recommended except in cases where only low-frequency sound effect samples are to be played, or when system performance constraints cause severe problems at higher data rates. Similarly, use of MAX_VAL may impose a significant burden on foreground CPU performance when drivers capable of 44 kHz operation are loaded. A few system-board and video-adapter combinations exhibit impaired DMA performance at higher physical sample rates, especially when monochrome text adapters are installed alongside ISA-based VGA adapters operating in high-resolution modes. Additionally, many sound adapters incorporate low-pass antialiasing filters which adapt themselves to the hardware sample rate. On these adapters, use of higher-than-necessary hardware sample rates will often result in a loss of playback fidelity when MSS must oversample the application's data. In general, best fidelity will be obtained by matching the hardware DMA and source sample data rates as closely as possible. Consequently, it is strongly recommended that the application select an explicit value for the DIG_HARDWARE_SAMPLE_RATE preference which is equal to the playback rate of the majority of the samples to be played, and let MSS's resampling capability handle the others.

This preference is only used under DOS. Under other platforms, the values specified in the call to AIL_open_digital_driver govern the final sound output quality.

Note that MSS does not permit hardware sample rates to be changed at any time after driver initialization. To establish a different hardware sample rate, it is necessary to shut down and reinitialize the driver. Note also that MSS drivers must be shut down in their opposite order of initialization.

Environment: DOS only.

Units: MIN_VAL, NOM_VAL, or MAX_VAL; or explicit frequency in hertz (samples per second).

Default Value: NOM_VAL.
DIG_USE_STEREO Under DOS, the DIG_USE_STEREO preference value determines whether or not stereo-capable hardware is actually used in stereo mode.

By default, DIG_USE_STEREO is set to the value NO, to keep DMA data rates at a minimum. An application which uses stereo digital audio samples, or which needs to control the stereo panning placement of mono samples, must include an AIL_set_preference(DIG_USE_STEREO,YES) statement before loading its digital audio driver(s).

If stereo samples are played on a monaural sound card, or on a stereo sound card with the DIG_USE_STEREO preference set to NO, the right-channel source data will be ignored.

As a rule, lower DMA data rates result in improved reliability in marginal situations. In particular, frequent video memory accesses - especially in super-VGA modes with ISA-based video subsystems - may interfere with high-speed DMA traffic, or vice versa. Disk or network traffic can also interfere with high-bandwidth DMA transfers, especially in the presence of virtual DMA hosts. DMA data rates may be kept to a minimum by setting DIG_HARDWARE_SAMPLE_RATE to NOM_VAL, or an explicit value of 22 Khz or less; leaving the DIG_USE_16_BITS preference value set to its default value of NO; and setting DIG_USE_STEREO to YES only in applications which can actually take advantage of stereo panning or stereo sample playback. This should not be taken as a warning to leave MSS's more advanced features unused, but rather as encouragement to keep hardware DMA rates no higher than necessary to meet the application's needs. There is no benefit in playing typical 11-or-22-Khz mono 8-bit samples with DIG_USE_16_BITS set to YES and DIG_HARDWARE_SAMPLE_RATE set to 44100 or MAX_VAL - in fact, sound quality may actually be degraded by the necessary resampling process.

This preference is only used under DOS. Under the other Miles platforms, the values specified by in call to AIL_open_digital_driver govern the final sound output quality.

Environment: DOS only.

Units: Boolean (YES / NO).

Default Value: NO.
DIG_USE_16_BITS Under DOS, the DIG_USE_16_BITS preference value determines whether or not 16-bit capable hardware is actually used in 16-bit mode.

By default, DIG_USE_16_BITS is set to the value NO, to keep DMA data rates at a minimum. An application which requires the absolute optimum fidelity available with a given sound card may wish to include an AIL_set_preference(DIG_USE_16_BITS,YES) statement before loading its digital audio driver(s).

As a rule, lower DMA data rates result in improved reliability in marginal situations. In particular, frequent video memory accesses - especially in super-VGA modes with ISA-based video subsystems - may interfere with high-speed DMA traffic, or vice versa. Disk or network traffic can also interfere with high-bandwidth DMA transfers, especially in the presence of virtual DMA hosts. DMA data rates may be kept to a minimum by setting DIG_HARDWARE_SAMPLE_RATE to NOM_VAL, or an explicit value of 22 Khz or less; leaving the DIG_USE_16_BITS preference value set to its default value of NO; and setting DIG_USE_STEREO to YES only in applications which can actually take advantage of stereo panning or stereo sample playback. This should not be taken as a warning to leave MSS's more advanced features unused, but rather as encouragement to keep hardware DMA rates no higher than necessary to meet the application's needs. There is no benefit in playing typical 11-or-22-Khz mono 8-bit samples with DIG_USE_16_BITS set to YES and DIG_HARDWARE_SAMPLE_RATE set to 44100 or MAX_VAL - in fact, sound quality may actually be degraded by the necessary resampling process.

See the DIG_ALLOW_16_BIT_DMA preference for more information about 16-bit DMA-based audio configuration.

This preference is only used under DOS. Under the other Miles platforms, the values specified by in call to AIL_open_digital_driver govern the final sound output quality.

Environment: DOS only.

Units: Boolean (YES / NO).

Default Value: NO.
DIG_DMA_RESERVE Under DOS, this preference determines the amount of physical (lower-1MB) memory set aside for DMA buffer construction at driver initialization time. It does not normally need to be changed unless memory in the lower 1MB of address space is at a premium. This value will never need to exceed 32,768 bytes. Space which is not used for the DMA half-buffer pair is reserved for internal use. Any changes made to this preference value must be made prior to digital driver installation.

Environment: DOS only.

Units: Bytes.

Default Value: 32,768.
DIG_ALLOW_16_BIT_DMA Under DOS, the DIG_ALLOW_16_BIT_DMA preference value determines whether or not 16-bit DMA channels may be used for 16-bit DMA transfers.

Many 16-bit PC sound cards can be configured to use one or more 16-bit DMA channels (5,6, and 7) to help ease the DMA bandwidth problems associated with 16-bit audio playback. By default, MSS allows these channels to be used if the driver supports them.

However, certain PC clones do not implement 16-bit DMA properly. Use of 16-bit DMA channels on these systems may cause lockups, noise, or other symptoms of audio system failure. If 16-bit digital audio is enabled by setting the DIG_USE_16_BITS preference to YES, end-users should be offered an opportunity to override the DIG_ALLOW_16_BIT_DMA preference via an installation option or command-line switch.

Any changes made to the DIG_ALLOW_16_BIT_DMA preference value must be made prior to installing the digital driver in question.

Environment: DOS only.

Units: Boolean (YES / NO).

Default Value: YES.
AIL_SCAN_FOR_HARDWARE Under DOS, if this preference value is set to NO, the MSS driver installation functions will not attempt to "auto-detect" sound hardware by using the list of common I/O configurations which is present in most MSS-compatible drivers. Environment variable-based detection will still be performed, as will any detection attempt based on an explicit IO_PARMS structure passed to the driver initialization function.

This preference may be useful to well-behaved application installation programs which ask permission from the user before attempting to verify the presence of a given sound card. RAD Game Tools recommends this practice in all cases.

Environment: DOS only.

Units: Boolean (YES / NO).

Default Value: YES.
AIL_ALLOW_VDM_EXECUTION Under DOS, MSS is unique among 32-bit PC sound systems in that its architecture permits it to be compatible with Microsoft Windows virtual DOS machines, or "DOS boxes." When AIL_ALLOW_VDM_EXECUTION is set to YES prior to loading any digital audio drivers, MSS will abide by certain rules involving DMA configuration for compatibility with Windows and other virtual-DMA hosts.

AIL_ALLOW_VDM_EXECUTION will not prevent dialog boxes with messages such as "The Sound Blaster is in use by another application" from appearing upon application startup. This message can often be avoided by waiting for a short period of time after the last sound is played by the Windows Multimedia Extensions before launching the MSS application's DOS session. The error which causes the dialog box to appear stems from design inadequacies in the Microsoft multimedia system, and is not a symptom of a problem with MSS (or any other DOS-based PC sound system).

Environment: DOS only.

Units: Boolean (YES / NO).

Default Value: YES.
DIG_LATENCY Under DOS, this preference governs the "lag time" between the execution of an MSS function call which affects digital audio playback, and the actual execution of the requested command. It determines the DMA half-buffer size to be configured when digital drivers are installed, as expressed in terms of the half-buffer playback time in milliseconds based on the DMA data rate in use.

The Miles Sound System digital audio mixer operates on the application's audio data in small chunks, called blocks. Part of the system's responsibility is to poll the hardware buffers in the background to determine when the next block of audio data from the application should be processed and copied into an empty DMA half-buffer. As an example, consider a hardware driver which is configured to play 16-bit audio at 20,000 Hz with a pair of 1,000-byte half-buffers. The driver's data rate is 40,000 bytes per second, implying a half-buffer playback rate of 40,000 / 1,000, or 40 buffer transitions per second.

At a rate of 40 times per second, then, a sample block equivalent to one half-buffer's worth of data is fetched from the application's sample data buffer at the current playback position. The samples are resampled if necessary to conform to the driver's hardware rate, converted between 8-bit and 16-bit formats where appropriate, mathematically scaled for volume and panpot control, algebraically added to data from other active samples, clipped, and copied into the driver's empty half-buffer to be played as soon as the other half-buffer finishes playing.

Consequently, any change made to a sample's playback characteristics - be it a change in volume, panpot value, pitch, start/stop status, or playback position - must wait until the next DMA half-buffer transition occurs before it can take effect.

The DMA latency setting represents a compromise between the ability of the system to maintain consistent sound quality in the presence of heavy interrupt loads associated with disk access and other sources, and its ability to respond quickly to requests from the application to start, stop, or otherwise affect the playback of digital audio samples. If too high a latency time is requested, annoying delays may occur between the time a sample is started and the time the user actually hears the sound. High DMA latency times are particularly undesirable when using "virtual wave synthesis" to trigger digital drum or instrument sounds with XMIDI sequence events. Conversely, too low a DMA latency setting may cause brief dropouts and "skips" during digital audio playback which takes place while disk, CD, or network access is occurring. This symptom may become quite pronounced on slower systems.

MSS's default DMA latency setting is 100 milliseconds, which is the longest recommended DMA latency period. (If the AIL_ALLOW_VDM_EXECUTION preference is set to its default value of YES, the DMA half-buffer size is limited to 2KB rather than 16KB. With higher sample rates, especially in combination with an 8-bit mono hardware channel, the actual DMA latency time will be much less than 100 milliseconds).

The minimum acceptable DMA latency figure will generally be in the range of 15-25 milliseconds. If extremely small DMA latency values are used, it may be necessary to increase the value of the DIG_SERVICE_RATE preference to give the system enough time to respond to the driver's DMA half-buffer transitions.

It is important to note that the DIG_LATENCY preference value is used during driver installation as a guideline only. Under the MSS architecture, DMA half-buffer sizes must be chosen from among the set of binary powers between 16 and 16,384 bytes. The DIG_LATENCY value, in conjunction with the DIG_HARDWARE_SAMPLE_RATE, DIG_USE_STEREO, and DIG_USE_16_BITS values, determines which of the possible buffer sizes is used. In most cases, the chosen buffer size will be only an approximation to the size which corresponds to the requested half-buffer playback time. If a change to DIG_LATENCY seems to have no effect as compared to the previous value, try making a slightly larger change in the same direction until the desired result is achieved.

Environment: DOS only.

Units: Milliseconds.

Default Value: 100.

Group: Preferences
Related Sections: Callbacks under Xbox 360, Miles DTS Provider for the Sony PS2, Sharing the CPU under Xbox 360, XMIDI For Loop Controller (116), XMIDI Sequence Branch (109)
Related Functions: AIL_DLS_open, AIL_MIDI_to_XMI, AIL_allocate_sample_handle, AIL_allocate_sequence_handle, AIL_branch_index, AIL_create_wave_synthesizer, AIL_get_preference, AIL_get_timer_highest_delay, AIL_init_sequence, AIL_install_DIG_driver_file, AIL_install_DIG_driver_image, AIL_open_digital_driver, AIL_register_timer, AIL_sample_output_levels, AIL_send_sysex_message, AIL_sequence_position, AIL_serve, AIL_set_preference, AIL_set_sample_playback_rate, AIL_set_sequence_volume, AIL_set_timer_divisor, AIL_set_timer_frequency, AIL_set_timer_period, AIL_startup
Related Basic Types: MILES_OPEN_DIGITAL_FLAGS
Related Structures: IO_PARMS
Related FAQs: How much latency does Miles have?, I'm setting a preference and it isn't having any effect - what's going on?, My sound is skipping on Windows or MacOS X - what can I do?, What's the best way to port my older Miles application to MSS 7?


Implementing Voice Chat

Discussion

When implementing voice chat, you use a combination of the Voxware voice chat codecs, the Miles digital input API, the Miles digital output API, and, finally, a networking layer. Since Miles itself doesn't supply a built-in networking layer (which is tough to do in the general case, because multi-player games need such strict control of the network pipe), it was difficult to decide how to expose and document the Miles voice chat features.

So, what we decided to do in the end, was to create a complete client-server voice chat example using the simplest possible networking layer (TCP with WinSock). With this solution, you can see a fairly full-featured application that you can adapt to your game's networking layer with little trouble. This means that this chapter will be fairly different than the rest of the Miles documentation - instead of a long list of functions, we'll walk through the client (MSSCHT.CPP) and the server (MSSCHTS.CPP) source code, step-by-step, describing each portion of the code in detail.

Next Topic (Voxware Voice Chat Codecs)

Implementing Voice Chat
Voxware Voice Chat Codecs
Working with Voice Input
Accessing the Codecs Directly with the RIB Interface
Performing the Compression and Decompression
Integrating the Codecs with your Networking Architecture
Mixing the Client Sound Data on the Server
Implementation Details
Bandwidth Optimization and Channel Reliability Tips


Voxware Voice Chat Codecs

Discussion

The Miles Sound System includes Audio Stream Interface (ASI)-based support for the popular Voxware™ MetaVoice compression and decompression libraries. Available for use by MSS developers on a royalty-free basis, this package includes the RT29 and RT24 fixed-rate codecs which are capable of compression and decompression of speech at bit rates of 2900 and 2400 bits per second, respectively; and the VR12 variable-rate codec which operates at varying bit rates between 600 and 1800 bits per second. Compared to standard 8-kHz 16-bit monaural voice input at 128,000 bits per second, these bit rates correspond to compression ratios between 50:1 and 100:1!

It's important, however, to understand that the Voxware codecs are not general-purpose audio compression resources. They achieve their spectacular performance by emulating the acoustical characteristics of the human vocal tract with specific, highly-refined DSP techniques and data models. Consequently, the MetaVoice technology should not be viewed as a competitor to IMA ADPCM, MP3, and other popular compression standards, but rather as a complementary technology that addresses the bandwidth/performance shortcomings of conventional codecs with respect to speech compression. Put another way, if you try to compress music or sound-effects samples with Voxware's low-bandwidth codecs, you'll be unlikely to recognize, much less appreciate, the decompressed result.

Using these high-performance codecs effectively in your application requires that you understand their capabilities and limitations, and plan your communications architecture carefully. To use the Miles Sound System's codecs for voice communications in a networked environment, you'll need to be comfortable with four basic aspects of the job. Most of these points are illustrated for demonstration purposes in the MSSCHTC.CPP (client) and MSSCHTS.CPP (server) example programs included with MSS.

Next Topic (Working with Voice Input)

Previous Topic (Implementing Voice Chat)

Group: Implementing Voice Chat


Working with Voice Input

Discussion

Before you can compress and transmit voice data, you'll need to acquire it. We've provided an easy-to-use set of API functions for voice input (see the Digital Input Services chapter), which allow the application to control and monitor the recording of audio data from the user's microphone or other input source. MSSCHTC.CPP demonstrates how to open a device for digital input and obtain incoming data from it by means of a callback function. The speech-compression codecs are not hard-wired into MSS's audio input/output architecture -- other voice-input mechanisms may be used by the application, including calling DirectSoundInput or the waveIn API directly for the absolute lowest possible latency. However, three aspects of voice input should be kept in mind regardless of how the data is obtained.

Use 16-bit mono audio at 8 kHz. The Voxware codecs are optimized for most efficient compression and reproduction at a sampling rate of 8 kHz. This is the standard sample rate used in almost all commercial and military speech-communication applications, including the US telephone system. The Voxware ASI codec implementations are designed solely for use with 16-bit PCM audio at 8 kHz, and will not support any other format.

Use full-duplex input. "Full duplex" simply means that the sound hardware is configured for simultaneous, independent recording and playback of audio data. With a full-duplex sound card, you don't have to stop playback in order to record speech, and vice versa. This doesn't mean that you have to leave recording on continuously, or that you have to continually send recorded audio data over the network - just that you don't have to shut down the playback subsystem in order to acquire input data. The Miles Sound System's integrated voice-input API supports only full-duplex audio hardware. Almost any sound card sold in the last five years will support full-duplex operation.

Choose voice-operated, continuous, or "push to talk" operation. Depending on the nature of your application (i.e., how "noisy" it is, how much network bandwidth is available, and under what circumstances your users will want to communicate) you'll need to decide how to control the flow of speech input.

Voice-operated (VOX) control may be appropriate in cases where the application doesn't generate a continuous stream of loud, raucous sound effects that would tend to cause false triggering. This can be implemented by leaving the input subsystem active all the time, and watching the incoming PCM input data buffers for an average signal level that exceeds a predetermined threshold, indicating that the user is speaking. Since you'll be dealing with 16-bit signed PCM data, you can simply examine the magnitude (absolute value) of individual samples or groups of samples in the buffer to determine their relative loudness. Typically it makes sense to average amplitude values over a period of time - several dozen milliseconds or more - in order to make sure the user has really begun speaking. VOX control may be an especially good match for applications that are bundled with telephone-operator-style headsets, or that otherwise require their use.

Continuous speech streaming may be useful in cases where network bandwidth is not particularly constrained, and/or your application supports only a few simultaneous users. This is the model implemented by the MSSCHTC and MSSCHTS example programs. It simply implies that the input API is left active on a constant basis, with all incoming data compressed and transmitted to the server for mixing and broadcasting.

Push-to-talk (PTT) offers a worthwhile compromise between the VOX and continuous operation models. The input subsystem may or may not be active on a continuous basis, but voice data is compressed and transmitted to the server only when the user holds down a particular key or input-device button. In noisy game environments with many simultaneous users, PTT is likely to be the mode of choice. In a bandwidth-saving variation on the PTT theme, each client could ask the server for "permission" to speak upon receiving a PTT input, allowing the server to limit the amount of incoming data from clients who are trying to speak at the same time.

Next Topic (Accessing the Codecs Directly with the RIB Interface)

Previous Topic (Voxware Voice Chat Codecs)

Group: Implementing Voice Chat


Accessing the Codecs Directly with the RIB Interface

Discussion

Most MSS applications don't need to access the library's ASI (Audio Stream Interface) layer directly - the details of communicating with individual ASI providers are encapsulated by high-level library functions such as the streaming and quick-integration APIs. However, real-time voice chat is an exception. To achieve good latency performance and full control over the compression/decompression process, it's necessary for the application to gain low-level access to the Voxware codecs by means of the ASI interface.

The ASI standard represents a very simple, generalized interface for MSS-compatible audio compression and decompression codecs. ASI uses the RAD Interface Broker (RIB) architecture to allow various codecs to be enumerated and selected on the basis of any of their properties and capabilities, including the standard file suffix of the data format they support. (See the RIB Architecture chapter for more information on the RIB interface model.) MSSCHTC.CPP and MSSCHTS.CPP demonstrate the process of selecting an ASI codec to handle a given input or output data format. The ASI codecs responsible for delivering the Voxware MetaVoice functionality are supplied in the MSSVoice.ASI file and include: include:

A 2900-bps high-quality fixed-rate compressor/decompressor. Suffix: ".V29"

A 2400-bps fixed-rate compressor/decompressor. Suffix: ".V24"

A 1200-bps low-bandwidth variable-rate compressor/decompressor. Suffix: ".V12"

By using each ASI codec's file suffix as a descriptor of the data format in use, MSSCHTC and MSSCHTC illustrate a way to make your chat system independent of any particular data format. When you run the Miles chat front-end (MSSCHAT.EXE), it calls MSSCHTC.EXE with the codec to use specified on the Windows command line. The client will try to find an ASI codec capable of both compression and decompression of data with the specified suffix type. Likewise, it will inform the server during the logon process that all data coming from the client will be compressed in the specified format, and that all data sent back to the client should be delivered in the same format. If both the client and the server are able to locate an ASI provider for the specified format, the link can be successfully established.

As an example of direct ASI codec access, MSSCHTC uses RIB services to locate an ASI encoder (compressor) for the data format specified on its command line.

//
// Find ASI provider to encode voice data for transmission
//
transmit_encoder = RIB_find_file_provider("ASI codec",
                                          "Output file types",
                                           suffix);
if (transmit_encoder == NULL)
{
   show_error("Error: No ASI provider available to encode data type %s\n", suffix);
   exit(1);
}
show_success("Using ASI provider %X to transmit data type %s\n",
              transmit_encoder,
              suffix);

Once the transmit encoder provider is obtained, MSSCHTC calls RIB to obtain an interface to various functions supported by the ASI codec. (As with all RIB components, it is the requestor's responsibility to specify the interface it wants to use when communicating with a RIB service provider).

//
// Get ASI stream interface for transmit encoder
//
RIB_INTERFACE_ENTRY ASISTR[] =
{
   { RIB_FUNCTION, "ASI_stream_open",           (U32) &XMIT_stream_open,           RIB_NONE },
   { RIB_FUNCTION, "ASI_stream_close",          (U32) &XMIT_stream_close,          RIB_NONE },
   { RIB_FUNCTION, "ASI_stream_process",        (U32) &XMIT_stream_process,        RIB_NONE }
}
RIB_request(transmit_encoder,"ASI stream",ASISTR);
//
// Open stream with codec, registering callback function
//
transmit_stream = XMIT_stream_open(0,
                                   transmit_stream_callback,
                                   0);
if (transmit_stream == NULL)
{
   show_error("Could not open stream encoder\n");
   exit(1);
}

Subsequently, a similar block of code is used to locate an ASI provider capable of decompressing the same data format as it is received from the server. The only difference in this case is the use of the "Input file types" property as the search key passed to RIB_find_file_provider.

//
// Search for ASI codec capable of processing specified input file type
//
// This ASI provider will be used to decode data sent from the server
// to the client
//
receive_decoder = RIB_find_file_provider("ASI codec",
                                         "Input file types",
                                          suffix);
if (receive_decoder == NULL)
{
   show_error("Error: No ASI provider available to decode data type %s\n",
              suffix);
   exit(1);
}

To illustrate a "well-behaved" application's interaction with an ASI provider, the client receive provider's interface contains requests for a few key properties, in addition to the same basic functions as those previously obtained from the transmit provider:

//
// Get ASI stream interface for receive decoder
//
RIB_INTERFACE_ENTRY RECVSTR[] =
{
   { RIB_FUNCTION,   "ASI_stream_property",  (U32) &RECV.ASI_stream_property,     RIB_NONE },
   { RIB_FUNCTION,   "ASI_stream_open",      (U32) &RECV.ASI_stream_open,         RIB_NONE },
   { RIB_FUNCTION,   "ASI_stream_seek",      (U32) &RECV.ASI_stream_seek,         RIB_NONE },
   { RIB_FUNCTION,   "ASI_stream_close",     (U32) &RECV.ASI_stream_close,        RIB_NONE },
   { RIB_FUNCTION,   "ASI_stream_process",   (U32) &RECV.ASI_stream_process,      RIB_NONE },
   { RIB_PROPERTY,   "Output sample rate",   (U32) &RECV.OUTPUT_SAMPLE_RATE,      RIB_NONE },
   { RIB_PROPERTY,   "Output sample width",  (U32) &RECV.OUTPUT_BITS,             RIB_NONE },
   { RIB_PROPERTY,   "Output channels",      (U32) &RECV.OUTPUT_CHANNELS,         RIB_NONE },
   { RIB_PROPERTY,   "Requested sample rate",(U32) &RECV.REQUESTED_RATE,          RIB_NONE },
};
RIB_request(receive_decoder,"ASI stream",RECVSTR);
//
// Open the receiver stream
//
// If the codec needs to inspect the stream data to
// configure itself, this call will block in the RECV_stream_CB()
// handler until the requested amount of data (typically only
// the first few bytes of the source stream) is received from the
// client.
//
RECV_read_cursor = 0;
RECV_write_cursor = 0;
RECV.stream = RECV.ASI_stream_open(0,
                                   RECV_stream_CB,
                                   0);
if (RECV.stream == NULL)
{
   show_error("Could not open stream decoder\n");
   exit(1);
}

These properties are used to request operation at the standard 8 kHz sample rate (HW_RATE) and to obtain the actual data format used by the codec to configure the output stream's HSAMPLE:

//
// Request codec output rate which matches hardware rate
//
U32 req_rate = HW_RATE;
RECV.ASI_stream_property(RECV.stream,
                         RECV.REQUESTED_RATE,
                         0, &req_rate, 0 );
//
// Stream is now open -- get its properties and set output
// sample properties accordingly
//
U32 nch, rate, bits;
RECV.ASI_stream_property(RECV.stream, RECV.OUTPUT_CHANNELS,    &nch,  0, 0 );
RECV.ASI_stream_property(RECV.stream, RECV.OUTPUT_SAMPLE_RATE, &rate, 0, 0 );
RECV.ASI_stream_property(RECV.stream, RECV.OUTPUT_BITS,        &bits, 0, 0 );
S32 type;
if (nch == 2)
{
   type = ( (bits == 16) ? DIG_F_STEREO_16 : DIG_F_STEREO_8 ) |
          ( (bits == 16) ? DIG_PCM_SIGN    : 0 );
}
else
{
   type = ( (bits == 16) ? DIG_F_MONO_16   : DIG_F_MONO_8 | )
          ( (bits == 16) ? DIG_PCM_SIGN    : 0 );
}
AIL_init_sample             (stream, type, 0);
AIL_set_sample_playback_rate(stream, rate);
receive_buffer_size = AIL_minimum_sample_buffer_size(dig, rate, type);
show_info("Receive stream format: %d channels, %d Hz, %d bits\n",nch,rate,bits);
show_info("Receive buffer size=%d\n",receive_buffer_size);

In reality, as noted previously, all MSS ASI providers used for voice communication are internally hardwired for operation with 16-bit monaural PCM audio at a sample rate of 8 kHz, so the above code to query the stream properties is not, strictly speaking, necessary. However, besides being good programming (or at least typing) practice, it serves as an example of how to obtain properties and set properties for an ASI stream. This general technique will be useful if the application wishes to take advantage of the Voxware warping and comfort-noise masking features described below.

Once the transmit and receive providers have been selected and their corresponding streams opened successfully, all that remains to be done on the client side with respect to ASI is the actual encoding and decoding of data. The following except from receive_ASI_thread_procedure in MSSCHTC.CPP illustrates the use of the ASI_stream_process function to turn compressed audio data back into playable PCM format:

//
// If fetch buffer empty, call ASI decoder to acquire decompressed data
// from server
//
// This will block in RECV_stream_CB() until enough data is received
// from the server to fill the fetch buffer
//
// Using the temporary fetch buffer allows us to read and decompress
// data while all of the receive buffers are full -- otherwise, we'd
// have to spin until an empty receive buffer becomes available
//
if (!fetch_buffer_full)
{
   S32 amount = RECV.ASI_stream_process(RECV.stream,
                                        fetch_buffer,
                                        receive_buffer_size);
   if (amount != receive_buffer_size)
   {
      //
      // Bad read
      //
      active = 0;
      return 0;
   }
   fetch_buffer_full = 1;
}

Next Topic (Performing the Compression and Decompression)

Previous Topic (Working with Voice Input)

Group: Implementing Voice Chat


Performing the Compression and Decompression

Discussion

Under the ASI standard, all compression and decompression takes place within the provider's ASI_stream_process function. This function is extremely open-ended in nature, and completely symmetrical with respect to compression and decompression. The application simply calls it with a request for any desired amount of compressed or decompressed data, from bytes to megabytes. ASI_stream_process fulfills as much of the application's request as possible from the provider's own internal buffers, if any data is left over from a previous call. Subsequently, it invokes the application callback function that was originally passed to ASI_stream_open to request that the application send it enough source data to enable it to fulfill the compression or decompression request. In this case, MSSCHTC.CPP's RECV_stream_CB function is called by the ASI_stream_open handler to obtain compressed data from the server, one "frame" at a time, until enough frames of data have arrived to fulfill the application's request:

// ---------------------------------------------------------------------------
// RECV_stream_CB()
// Runs from client receive thread
// ---------------------------------------------------------------------------
S32 CALLBACK RECV_stream_CB(U32       user,
                            void FAR *dest,
                            S32       bytes_requested,
                            S32       offset)
{
   //
   // A seek offset of 0 occurs only when the stream is opened (initial seek to
   // beginning to determine stream characteristics) and when the first frame
   // of the stream is read after opening (when actually beginning to stream
   // data).  Since we are dealing with a non-seekable input stream, we
   // must handle this second case by maintaining a separate read and write
   // cursor in the frame buffer.  The second 0-offset seek is guaranteed
   // to occur while the initial frame data is still in the buffer.
   //
   // Most voice codecs won't perform any seek operations at all -- this
   // functionality is here primarily to support MP3 streaming and similar
   // operations.  A chat server designed strictly for use with the Voxware
   // codecs can safely ignore the offset parameter altogether.
   //
   //
   if (offset != -1)
   {
      RECV_read_cursor = offset;
   }
   //
   // Data will typically be requested one frame at a time by the ASI codec
   // (although frame header components may be requested separately, a few words
   // at a time).  A return value of less than bytes_requested indicates the
   // end of the stream has been reached.  We don't support fragmented frames,
   // so we'll return 0 to the codec if the client disconnects while we're
   // polling it for data.  Any ASI codec designed for compatibility with
   // IP streaming MUST accept 0-byte return values at any stage.
   //
   S32 needed = bytes_requested;
   while (1)
   {
      //
      // Get as much data as possible from frame buffer
      //
      if (RECV_read_cursor < RECV_write_cursor)
      {
         S32 n = min(needed,
                     RECV_write_cursor - RECV_read_cursor);
         memcpy(dest,
               &RECV_frame[RECV_read_cursor],
                n);
         dest              = ((C8 *) dest) + n;
         RECV_read_cursor += n;
         needed           -= n;
      }
      //
      // If all requested data has been read, return
      //
      if (needed <= 0)
      {
         //
         // Keep read/write cursors in first half of frame buffer
         //
         if (RECV_read_cursor >= RECEIVE_FRAME_SIZE)
         {
            RECV_read_cursor  -= RECEIVE_FRAME_SIZE;
            RECV_write_cursor -= RECEIVE_FRAME_SIZE;
         }
         return bytes_requested;
      }
      //
      // We need more data -- read it into the frame buffer
      //
      S32 result = NET_poll_for_data(&RECV_frame[RECV_write_cursor],
                                      needed);
      if (result == -1)
      {
         //
         // Client disconnected, return 0 to abort current frame
         //
         return 0;
      }
      if (result == 0)
      {
         //
         // No data available yet
         //
         Sleep(10);
      }
      else
      {
         //
         // Advance the write cursor
         //
         RECV_write_cursor += result;
      }
      //
      // Block until more data comes in or server disconnects
   }
}

As the comments suggest, this code is somewhat more robust than it has to be for simple voice communication with the Voxware codecs. Many ASI decompressors, notably the MP3 decoder, can output different PCM data formats depending on the exact format of the compressed source data. In such a case, the application needs to be able to determine the sample format required to play the decoded data immediately after calling the ASI_stream_open function. So a typical ASI codec must examine the first few bytes of the data when opening a stream, in order to report the stream's format to the application. This is the only case in which a "seek" operation must be supported by the codec when dealing with streamed data, so it's a good practice to support valid offset parameters in an ASI decompressor's callback function if you expect to support more general codecs in the future. (Typically the ability to seek 1 or 2 KB backwards in a stream after the first frame is fetched is sufficient for most popular data formats).

Turning uncompressed PCM data from the input API or data file into compressed data suitable for transmission to the server is an almost identical process, thanks to the inherent symmetry of the ASI specification. MSSCHTC.CPP's transmit_ASI_thread_procedure calls the transmit ASI provider as follows:

//
// See if more transmit data is needed
//
if (current_send_offset == TRANSMIT_PACKET_SIZE)
{
   //
   // Request data from ASI encoder to send to server
   //
   // This will block in XMIT_stream_CB( ) until enough input
   // data is available to satisfy the request
   //
   S32 amount = XMIT_stream_process(transmit_stream,
                                    send_buffer,
                                    TRANSMIT_PACKET_SIZE);
   if (amount != TRANSMIT_PACKET_SIZE)
   {
      //
      // Bad read
      //
      active = 0;
      return 0;
   }
   current_send_offset = 0;
}

As in the receiver code above, the XMIT_stream_process function calls the application-supplied callback function XMIT_stream_CB to fetch enough data to fulfill the application's request. In this case, XMIT_stream_CB blocks until sufficient data is available from the input API:

// ---------------------------------------------------------------------------
// XMIT_stream_CB( )
// ---------------------------------------------------------------------------
S32 CALLBACK XMIT_stream_CB(U32       user,
                            void FAR *dest,
                            S32       bytes_requested,
                            S32       offset)
{
   //
   // Block transmission thread in this routine until specified
   // number of bytes available from input, or disconnection occurs
   //
   S32 bytes_sent = 0;
   while (bytes_requested > 0)
   {
      //
      // Allow other threads to run
      //
      Sleep(3);
      //
      // Exit if transmit thread killed by main thread
      //
      // Returning 0 here will cause transmit_thread_procedure() to exit
      // when its ASI_stream_process( ) call fails
      //
      if (!threads_active)
      {
         return 0;
      }
      //
      // Get input buffer to send
      //
      if ((input_buffer_tail == -1) ||
          (input_buffer_tail == input_buffer_head))
      {
         //
         // No input buffers available
         //
         continue;
      }
      //
      // Transmit data from input buffer at queue tail
      //
      C8 FAR *src       = &input_buffer [input_buffer_tail] [input_read_offset];
      S32     src_avail = INPUT_BUFFER_SIZE - input_read_offset;
      S32 send_amount = min(bytes_requested,
                            src_avail);
      memcpy(dest,
             src,
             send_amount);
      dest               = ((C8 *) dest) + send_amount;
      input_read_offset += send_amount;
      bytes_requested   -= send_amount;
      bytes_sent        += send_amount;
      if (input_read_offset == INPUT_BUFFER_SIZE)
      {
         //
         // Entire buffer has been sent; advance tail pointer
         //
         if (input_buffer_tail == N_INPUT_BUFFERS-1)
         {
            input_buffer_tail = 0;
         }
         else
         {
            ++input_buffer_tail;
         }
         input_read_offset = 0;
      }
   }
   return bytes_sent;
}

Use of the ASI codec interface in MSSCHTS.CPP is very similar to the above examples in MSSCHTC.CPP.

Next Topic (Integrating the Codecs with your Networking Architecture)

Previous Topic (Accessing the Codecs Directly with the RIB Interface)

Group: Implementing Voice Chat


Integrating the Codecs with your Networking Architecture

Discussion

When it comes to picking a topology for your voice-networking subsystem, several options are available. Which one is right for your application will be determined by such factors as the nature of your application's existing network support (if any), availability of server-side and client-side network bandwidth, and availability of server-side and client-side processing power.

In a pure client-server model, as illustrated by the MSSCHTC and MSSCHTS example applications, only one compression and one decompression thread run on each client. Data is acquired at the client, compressed, and transmitted to the server. At the server side, incoming data from each client is decompressed and mixed with data from other clients, then transmitted back to each client. Each stream transmitted from the server must be mixed and compressed discretely to avoid echoing a given client's contribution to the mix back to that client. Server-side I/O bandwidth and processing overhead can be quite high unless special measures are taken to optimize bandwidth. Such measures might include permission-to-talk schemes such as outlined in the Push-to-talk section above, and/or simply limiting the number of clients allowed to contribute to the output mix at any given time.

A peer-to-peer model implies that each client runs one compression thread and as many decompression threads as are necessary to receive speech from all other clients who may be speaking. All decompression and mixing takes place redundantly at each client, and all compressed data must be sent to every other client. Lacking an adequate IP-multicast-compatible transport layer, the pure peer-to-peer model does not scale adequately beyond a few clients in the general case. However, the peer-to-peer model may represent the simplest and most efficient way to implement person-to-person IP telephony applications and two-player games.

A distributed-server model may be an excellent compromise in massively-multiplayer games and online communities, especially in cases where centralized server resources are limited or nonexistent. In a distributed-server environment, each client station acts as a mixing server for a limited number of other clients, typically partitioned by "channels" or other logical divisions between groups of users that don't need to talk to each other on a continuous basis. Communication between any two users may still be established on demand by means of appropriate interfaces in the game or online environment, subject to a given number of simultaneous "connections" allowed at each client.

Next Topic (Mixing the Client Sound Data on the Server)

Previous Topic (Performing the Compression and Decompression)

Group: Implementing Voice Chat


Mixing the Client Sound Data on the Server

Discussion

Any model other than peer-to-peer will require that data be buffered and mixed on one or more servers, in preparation for transmission to clients. Fortunately, given the tight constraints on PCM data formats used for voice communication, it's difficult to imagine an easier audio programming job. Mixing of 16-bit signed PCM data is accomplished by means of simple algebraic addition of the corresponding samples from each client buffer, followed by a hard clamping operation to avoid distortion due to sample data overflow. The lack of any need for sample rate conversion, volume scaling, or reformatting enables a simple C/C++ loop to do the job efficiently.

It's important to mix the data from each client at higher-than-16-bit precision, performing the clipping operation only after all samples have been added. Doing so actually reduces the amount of sample points that ultimately have to be clipped, since each incoming waveform sample point has a roughly equal chance of causing an overflow condition or canceling an existing one. MSSCHTS.CPP illustrates how 16-bit sample data may be mixed at 32-bit precision:

// ------------------------------------------------------------
// Merge data from all active clients into each client's
// mixer buffer
// ------------------------------------------------------------
for (i=0; i < N_CLIENTS; i++)
{
   CLIENT *C = &clients[i];
   //
   // If not actively streaming, skip further foreground processing
   //
   if (!C->in_use)
   {
      continue;
   }
   //
   // Clear client's mixer buffer to signed-PCM 0 value (0x0000)
   //
   memset(C->mixer_buffer,
          0,
          sizeof(C->mixer_buffer));
   //
   // Add samples from each contributing client's decode buffer to
   // target's mixing buffer
   //
   for (S32 j=0; j < N_CLIENTS; j++)
   {
      CLIENT *SRC = &clients[j];
      //
      // Avoid echoing each client's own traffic back to it, unless
      // we've enabled local echo as a diagnostic option
      //
      if (SendMessage(hear,BM_GETCHECK,0,0)==0)
      {
        if (i == j)
        {
           continue;
        }
      }
      //
      // Skip inactive or newly-logged-on clients that don't have
      // enough data buffered yet
      //
      if (SRC->samples_to_mix == 0)
      {
         continue;
      }
      //
      // Add 16-bit data to 32-bit output buffer
      //
      S16 *src  = SRC->fetch_buffer;
      S32 *dest = C->mixer_buffer;
      for (S32 m=0; m < samples; m++)
      {
         dest[m] += src[m];
      }
   }
   //
   // Clip and copy contents of client's mixer buffer to output buffer
   //
   C8 output_buffer[TRANSMIT_QUEUE_SIZE];
   S32 *src  =         C->mixer_buffer;
   S16 *dest = (S16 *) output_buffer;
   for (S32 m=0; m < samples; m++)
   {
      S32 s = src[m];
      if (s < -32768)
      {
         *dest++ = -32768;
      }
      else if (s > 32767)
      {
         *dest++ = 32767;
      }
      else
      {
         *dest++ = S16(s);
      }
   }
   //
   // Add buffer to transmit queue
   //
   C->transmit->put_data(output_buffer,
                         samples * sizeof(S16));
}

Next Topic (Implementation Details)

Previous Topic (Integrating the Codecs with your Networking Architecture)

Group: Implementing Voice Chat


Implementation Details

Discussion

MSSCHTC.CPP and MSSCHTS.CPP both rely heavily on multithreading to keep the various compression and decompression processes out of each others' way. Most of the execution time in each thread is spent waiting for data to become available from either WinSock or the mixer. The Voxware ASI codecs are guaranteed to be 100% thread-safe, but especially on the server side with two threads per client, it makes sense to be extremely careful with any shared variables and data structures to avoid deadlocks. MSSCHTS.CPP's mixer loop, which runs in the same thread as WinMain, uses CQueue, a rudimentary circular-buffer template, to isolate data being received and transmitted to each client.

Note that the data structures and synchronization methods in MSSCHTS and MSSCHTC have been chosen primarily for simplicity, and are intended more for illustrative purposes than as an attempt to wring every last cycle of performance out of the Win32 thread scheduler and WinSock API.

Next Topic (Bandwidth Optimization and Channel Reliability Tips)

Previous Topic (Mixing the Client Sound Data on the Server)

Group: Implementing Voice Chat


Bandwidth Optimization and Channel Reliability Tips

Discussion

Any real-world implementation of networked voice communication is likely to be a complex affair. Below are some hints on how to get the most out of the MSS voice chat codecs.

Use UDP networking. The MSSCHTS and MSSCHTC example programs delivered with MSS use TCP/IP with the Winsock 1.X API, for simplicity. It's important to note, though, that TCP/IP is a stream-oriented rather than a packet-oriented protocol. TCP/IP provides certain guarantees of data integrity, but those guarantees come at a price: packet size and delivery latency. Because the MSS chat codecs operate on a frame-by-frame basis, it's more efficient to transport the data for each frame in an independent UDP datagram, rather than forcing the TCP layer to treat the compressed data as fragments of a continuous stream. The UDP protocol imposes significantly less overhead on data communications than TCP, but it does require significantly more programming effort to handle missing or duplicated packets in a robust fashion. If you are working on a high-performance real-time multiplayer game, chances are you're already using UDP. In such a case, your task is simply to add ASI compression and decompression support to your existing network code.

Optimize the size of each transmitted frame. There is a subtle inefficiency in the general-purpose ASI interface that becomes evident when working with the Voxware codecs. The compressed frame size of each ASI codec is a fixed number of bytes, obtainable by querying the "Maximum frame size" property on the decompressor provider (or, alternatively, by querying the "Minimum input block size" property on an open decompressor stream). The inefficiency arises from the minuscule size of a frame of Voxware-compressed data. The V29 codec uses a 67-bit frame; the V24 codec a 54-bit frame; and the V12 codec deals with frame sizes which vary between 2 and 41 bits. The ASI frame size property always reports frame size at byte granularity, resulting in the effective waste of several bits per frame - which is a significant quantity of data at such small frame sizes! If your networking layer is efficient enough to take advantage of otherwise-unused bits in outgoing and incoming voice packets, or if you wish to pack multiple frames' worth of data into a single transmission unit, you may want to query the S32 "Actual bits encoded last frame" property in the encoder's "ASI stream" interface, to determine the exact number of bits in each compressed frame.

Use warping and comfort-noise masking to adapt to varying network conditions. Two of the most powerful, network-friendly features of the Voxware MetaVoice codecs delivered with the Miles Sound System are "warping" and "comfort noise." The ASI codecs expose these features through the F32 "Warp factor" and S32 "Comfort noise frames" properties in the decoders' "ASI stream" interfaces.

Warping enables the application to slow down or speed up the rate at which the Voxware decoder consumes network data. A warp factor of 1.0 causes decoded data to be produced at the standard Voxware rate of 180 bytes per frame, every frame. A warp factor of greater than 1.0 causes the Voxware codec to "slow down" the generation of output voice data, occasionally generating an extra 180-byte output frame without demanding any new input data. Interestingly, the voice does not undergo any pitch change whatsoever! Similarly, a warp factor of less than 1.0 causes the codec to "speed up" the output voice data, occasionally swallowing an input frame without generating any output data for that frame. By varying the warp factor around 1.0, your code can dynamically adjust for changes in packet arrival times without resorting to large buffers that may substantially increase perceived latency.

Comfort noise is a similar bandwidth-optimization feature. When a network connection becomes so unreliable that the latencies can't be easily handled by warping alone, you can set the "Comfort noise frames" property to a non-zero value. Subsequent calls to the decoder's ASI_stream_process function will not fetch any data from the application callback, but instead will generate a "masking tone" based on the previous characteristics of the stream's voice, such that a human listener is unlikely to notice one or two missing packets. This is substantially preferable to the usual alternative of allowing the stream to drop out completely. Just set the "Comfort noise frames" property to the number of subsequent frames you would like to mask, and the codec will do the rest.

Neither MSSCHTC.CPP nor MSSCHTS.CPP implements comfort noise or warping, or any other form of packet-arrival timing compensation. To use warping and comfort noise within the context of your own networking code, simply follow these examples:

//
// Get property handles for warping and comfort noise
//
HPROPERTY WARP_FACTOR,
COMFORT_NOISE_FRAMES;
RIB_INTERFACE_ENTRY ASISTR[] =
{
   PR("Warp factor",            WARP_FACTOR),
   PR("Comfort noise frames",   COMFORT_NOISE_FRAMES),
};
RIB_request(ASI,"ASI stream",ASISTR);
//
// Adjust Voxware warping/masking properties
//
if (/* need to increment warp factor */)
{
   F32 warp;
   ASI_stream_property(stream, WARP_FACTOR, &warp, 0, 0 );
   if (warp < 3.0F) warp += 0.1F;
   ASI_stream_property(stream, WARP_FACTOR, 0, &warp, 0 );
}
if (/* need to decrement warp factor */)
{
   F32 warp;
   ASI_stream_property(stream, WARP_FACTOR, &warp, 0, 0 );
   if (warp > 0.1F) warp -= 0.1F;
   ASI_stream_property(stream, WARP_FACTOR, 0, &warp, 0 );
}
if (/* need to request 1 frame of comfort noise */)
{
   S32 c;
   ASI_stream_property(stream, COMFORT_NOISE_FRAMES, &c, 0, 0 );
   c = c + 1;
   ASI_stream_property(stream, COMFORT_NOISE_FRAMES, 0, &c, 0 );
}

Previous Topic (Implementation Details)

Group: Implementing Voice Chat


Miles Sound System Tools Reference

Discussion

The Miles Sound System comes with a handy set of tools that you can use to prepare your audio for MSS.

Even better, full source code is available to all of the tools in the "\src\tools" directory.

Miles Sound System Tools Reference
Miles Sound Studio
Miles Sound Player
MIDIECHO for Windows - MIDI Data Receiver and Interpreter
MIDIECHO for MacOS - MIDI Data Receiver and Interpreter
MIDIECHO for DOS - MIDI Data Receiver and Interpreter
SETSOUND - MSS Sound Configuration Utility
GLIB - Extended MIDI (XMIDI) Global Timbre Librarian
CLAD - Creative Labs and Ad Lib (TM) Converter
MIDILOG - MIDI File Event Filter
MIDIREC- Standard MIDI File Recorder
WAVELIB - Wave Synthesizer Librarian


Miles Sound Studio

Discussion

The Miles Sound Studio is a utility capable of all of the common tasks that a Miles Sound System user will require. It contains tools for digital sound files, MIDI files, and DLS files. The Miles Sound Studio is available for Windows or MacOS.

All of the neat things that the Miles Sound Studio can do are available from the buttons along the bottom of the window. In Windows, you simply highlight a file, and then click one of the buttons. In MacOS, you drag a file from a Finder folder window onto the button to apply. We'll describe each button next.

The Compress button: this option will compress either a digital wave file, a DLS file, or DLS data embedded in an XMIDI file with IMA ADPCM or MPEG Layer 3 compression. ADPCM compression provides a 4-to-1 space-savings with very little quality loss, MP3 provides 11-to-1 space-saving with no quality loss. ADPCM and MP3 compressed wave files can be played back directly by the Miles Sound System.

Note that compressed DLS files generally have the extension ".MLS".

The Decompress button: this option will decompress either a digital wave file, a MLS file, or MLS data embedded in an XMIDI file that was previously compressed with the Compress option. Note that this isn't a lossless operation - compressing and then decompressing a file will result in different sound data.

The Merge XMI with DLS button: this option will merge together a DLS or MLS file into a MIDI or XMIDI file. This allows you distribute your MIDI files with built-in instruments - kind of like a high-rent MOD file! For further space-savings, you can also choose to remove the instruments that aren't used in the MIDI sequence. You can even compress the instrument data as it is merged into the new file. You must highlight both a DLS and a MIDI file for this option. To highlight more than one file at a time, hold the 'Control' key down as you click on the files.

Note that XMIDI files with embedded DLS data generally have the extension ".MSS".

The Unmerge XMI and DLS button: this option will unmerge the XMIDI and DLS pieces of a merged-XMIDI file into two separate files. This is useful when you need to edit the DLS instruments that were previously embedded into a merged-XMIDI file.

The Filter DLS with MIDI button: this option will use one or more MIDI or XMIDI files to filter out unused instruments in a DLS or MLS file. This option allows you to shrink huge DLS files (General MIDI sets, for example) into smaller DLS files that include only the instruments that are used by the specified MIDI files. You can highlight as many MIDI files as you want to filter with, so you can even create perfect 'application-wide' DLS files (DLS files that can play any MIDI file in your application). If the data is uncompressed, you can also choose to compress it as it is filtered. You must highlight both a DLS and at least one MIDI file for this option. To highlight more than one file at a time, hold the 'Control' key down as you click on the files.

The Convert to XMIDI button: this option will convert Standard MIDI Format 0 and Format 1 sequence files to the Extended MIDI (XMIDI) format used by the Miles Sound System's Version 2.0 and Version 3.0 drivers. This conversion preserves all of the information needed to faithfully reproduce the sequence's original sound, while discarding elements of the MIDI storage format that are redundant, inefficient, or otherwise unnecessary for real-time playback.

An XMIDI file containing a single translated MIDI sequence often requires from 10% to 30% less storage space, and can be performed with substantially less background processing time. The MIDI data track is compressed mostly by the elimination of all Note Off messages, which is made possible by appending each note's duration in quantization intervals to its original Note On event. Track-specific MIDI meta-events (such as Sequence/Track Name, Instrument Name, and End of Track events) are stripped from the data stream, while a single End of Track meta-event (FF 2F 00) is placed at the end of the XMIDI sequence.

In addition to the prequantized MIDI event stream, the XMIDI sequence format also includes information such as master lists of Global Timbre Library entries needed by the sequence and target offsets for any Sequence Branch Index controllers present in the sequence. To aid developers with specialized needs, XMIDI files are stored in accordance with Electronic Arts' Interchange File Format (EA IFF 85) standard . For example, using conventional IFF access routines, MSS applications may load and interpret XMIDI timbre list (TIMB) chunks manually, using the data to prepare the synthesizer for immediate playback of sequences at a later time.

Refer to the Extended MIDI (XMIDI) Specification Section for a detailed description of the XMIDI IFF structure.

Note that XMIDI files generally have the extension ".XMI".

The Convert to RAW button: this option will convert a highlighted digital wave file into a RAW file. A raw file is a digital sound file that has no header or trailer information (sometimes useful in low-level streaming sound playback).

Note that RAW sound files generally have the extension ".RAW".

The File Type Button: this option will display the file type of the highlighted file. It's handy when you can't remember if you already embedded DLS data into a file, or whether you compressed it, etc, etc. It can detect PCM wave files, IMA ADPCM wave files, other wave files, standard MIDI files, XMIDI files, XMIDI files with embedded uncompressed DLS data, XMIDI files with embedded compressed DLS data, uncompressed DLS files, and compressed DLS files.

The MIDI List button: this option will display the contents of the selected MIDI file. This list file will display every MIDI event in the file. It is useful for trouble-shooting problem MIDI files. You can also choose to view the Roland MT-32 / LAPC-1 Programmer's Reference Guide with the MIDI listing. In addition to all standard MIDI file events, this option also recognizes and displays each Miles Sound System-specific meta-event and Extended MIDI Control Change event.

Below is a sample MIDI list:

MIDI Listing version 4.0a         Copyright (C) 1991-98 RAD Game Tools, Inc.
-------------------------------------------------------------------------------
Offset $0000: Chunk MThd, length $0006
    MIDI file format: 1
    # of tracks: 2
    MIDI division: 120 delta-time ticks per quarter-note
Offset $000E: Chunk MTrk, length $0019
    DTime 0000: meta-event: key signature 0 0
    DTime 0000: meta-event: tempo in uS/MIDI quarter-note = 666666
    DTime 0000: meta-event: time signature 4/4, c = 024, b = 008
    DTime 0000: meta-event: end of track
Offset $002F: Chunk MTrk, length $0048
    DTime 0000: meta-event: sequence/track name "PIANO"
    DTime 0000: meta-event: instrument name "Acou Piano 2"
    DTime 0000: Ch 02 program change to 001
    DTime 0000: Ch 02 main volume MSB = 127
    DTime 0000: Ch 02 note 048 on, attack velocity 091
    DTime 0092: Ch 02 note 048 off
    DTime 0028: Ch 02 note 048 on, attack velocity 088
    DTime 0106: Ch 02 note 048 off
    DTime 0014: Ch 02 note 048 on, attack velocity 098
    DTime 0079: Ch 02 note 048 off
    DTime 0001: Ch 02 note 050 on, attack velocity 088
    DTime 0035: Ch 02 note 050 off
    DTime 0007: Ch 02 note 052 on, attack velocity 090
    DTime 0091: Ch 02 note 052 off
    DTime 0027: Ch 02 MSS callback trigger controller 000
    DTime 0000: meta-event: end of track

The DLS List button: this option will display the contents of the selected DLS file. This list file will display all of the instrument information inside the DLS file. You can also choose whether to view the articulation data for each instrument. Refer to the Downloadable Sounds Level 1 Version 1.0 specification, available at the M.M.A. web-site, for guidelines on the interpretation of DLS data files.

Next Topic (Miles Sound Player)

Group: Miles Sound System Tools Reference
Related Sections: Extended MIDI IFF (.XMI) Structure, Miles Sound Player


Miles Sound Player

Discussion

The Miles Sound Player is an easy-to-use application for Win32 and Win64 that can play PCM wave files, IMA ADPCM wave files, MPEG Layer 3 files, Ogg Vorbis files, MIDI files, and XMIDI files. It can play any of the MIDI types with the system's MIDI hardware or with the MSS software synthesizer. The Miles Sound Player is available for Windows or MacOS.

This application is launched from the Miles Sound Studio when you choose to play a sound file.

Controls:

The slider allows you to both view and change the current playback position.

The CPU indicator tells you what percentage of the CPU is being used by the digital processor and/or software synthesizer.

The Filter switch turns on and off sound filtering - filtering takes a little extra CPU time.

The Reverb switch turns on and off global reverb - reverb also takes extra CPU time.

The Rate pull down allows you to choose the rate for digital synthesis - the faster the rate, the more CPU time is required.

The 16-bit switch turns on and off 16-bit output mode - 16-bit quality takes very little extra CPU time.

The Stereo switch turns on and off stereo output mode - stereo takes extra CPU time.

The Save Portion button allows a portion of an MP3 file to be clipped and saved with the loop-editor control. (For more information on auditioning loops in digital audio files with the Miles Sound Player, see the I'm getting a glitch when I loop an MP3 or ADPCM file - what can I do? FAQ.)

The MIDI pull down allows you to choose five different MIDI playback options:

"Auto-choose MIDI device": tells the player to use the system MIDI hardware for normal MIDI and XMIDI sequences, and to use the software-synthesizer for XMIDI files with embedded DLS data.

"Use MIDI hardware": tells the player to use the system MIDI hardware in all cases.

"Use software synthesizer": tells the player to use the Miles software synthesizer in all cases.

"Use Vortex DLS hardware": tells the player to use the Aureal Vortex DLS hardware for playback.

"Use SonicVibes DLS hardware": tells the player to use the S3 SonicVibes DLS hardware for playback. To use the software synthesizer with normal MIDI and XMIDI sequences, you must also choose a DLS file as the instrument set - click the "GM DLS file..." button to choose this DLS file.

Next Topic (MIDIECHO for Windows - MIDI Data Receiver and Interpreter)

Previous Topic (Miles Sound Studio)

Group: Miles Sound System Tools Reference
Related Sections: Miles Sound Studio
Related FAQs: I'm getting a glitch when I loop an MP3 or ADPCM file - what can I do?


MIDIECHO for Windows - MIDI Data Receiver and Interpreter

Discussion

The MIDIECHO for Windows program receives incoming MIDI Channel Voice and System Exclusive messages via a standard Windows midiIn driver, and sends them to a specified Miles Sound System Extended MIDI (XMIDI) driver.

MIDIECHO is a valuable resource for musicians who wish to develop music and sound-effects arrangements for MSS applications. Composers can receive immediate feedback when developing IBM-specific XMIDI compositions on a Macintosh or Atari ST-based MIDI sequencer platform, simply by connecting the host's MIDI interface to a reasonable-quality MIDI interface on a "slave" PC system running MIDIECHO.

When starting MIDIECHO, you must choose the capture and playback options.

You can choose the drivers for MIDI input, MIDI output, and digital output. Digital output is used for the software synthesizer and digital trigger sound effects with wave library files (now obsolete - you should use DLS for all future digital sample triggering). You can also choose the DLS Provider DLL to use - use MSS32.DLL for the software synthesizer, S3BASE.DLL for Sonic Vibes DLS hardware, or VORT_DLS.DLL for Aureal Vortex DLS hardware.

Once you've made all of your choices, click the Start MIDI Echo button, and the main MIDI Echo text window will appear. When playing complicated MIDI sequences, the display may fall behind the MIDI music - to avoid this, simply press Alt-Enter to switch the screen to full-screen text mode.

When MIDIECHO is running, the + and - keys may be used to adjust the "voice alert limit," or the number of notes which MSS assumes the synthesizer in use can play simultaneously. During a MIDI performance, MIDIECHO presents a continuously-updated graphical display of polyphonic note activity. When the voice alert limit is exceeded, the portion of the bar graph to the right of the limit indicator will be shown in bright red, and the "total overflows" indicator above the graph will be incremented. This feature may be helpful when diagnosing note "dropout" problems that occur due to partial overflow.

When running on slower PC platforms with dense MIDI traffic, MIDIECHO may exhibit undesirable tempo variations due to program overhead. If this problem occurs, the T key can be used to disable the continuously scrolling MIDI event trace which appears in MIDIECHO's uppermost window.

The A key (All Notes Off) can be pressed at any time to "kill" any stuck notes which may occur while running MIDIECHO.

During playback, if a combination of XMIDI Patch Bank Select controller and MIDI Program Change number values is used to set up a timbre which cannot be found in the specified Global Timbre Library file, MIDIECHO will complain with an error message. The E key can be used to enable or disable a beep tone from the PC speaker when note overflow occurs, or when instrument-loading errors are reported.

The F key (Filter) can be pressed to toggle the software synthesizer's filtering mode.

The R key (Reverb) can be pressed to toggle the software synthesizer's reverb mode.

MIDIECHO re-transmits incoming data on all 16 MIDI channels to the MSS driver via the AIL_send_channel_voice_message call. The program retransmits all MIDI Channel Voice messages. (MIDI System Exclusive messages are retransmitted as well, but this feature should be used with caution since "timing slips" inherent in System Exclusive transmission can cause strange, misleading effects in the music).

MIDIECHO is intended to receive normal MIDI Channel Voice data, not synthesizer-ready XMIDI data. Timing problems may occur if a dense XMIDI data stream (as from a Miles Sound System application or the MSS Version 2.0 CAKEPORT driver) is fed to the MIDIECHO host's input port.

Next Topic (MIDIECHO for MacOS - MIDI Data Receiver and Interpreter)

Previous Topic (Miles Sound Player)

Group: Miles Sound System Tools Reference
Related Sections: MIDIECHO for DOS - MIDI Data Receiver and Interpreter, MIDIECHO for MacOS - MIDI Data Receiver and Interpreter
Related Functions: AIL_send_channel_voice_message


MIDIECHO for MacOS - MIDI Data Receiver and Interpreter

Discussion

The MIDIECHO for Mac program receives incoming MIDI Channel Voice and System Exclusive messages via a QuickTime MIDI input, and sends them to a specified Miles Sound System Extended MIDI (XMIDI) driver.

Note: To use a MIDI keyboard, you have to install the Opcode OMS library by Opcode Systems, Inc.

MIDIECHO can be useful for musicians who wish to develop music and sound-effects arrangements for MSS applications. Composers can receive immediate feedback when playing compositions on a MIDI sequencer platform, simply by connecting the host’s MIDI interface to a reasonable-quality MIDI interface on a "slave" Mac system running MIDIECHO.

When starting MIDIECHO, you must choose the capture and playback options.

With the drop-down menus, "MIDI Input Device" and "MIDI Output Device", you can choose the drivers for MIDI input and MIDI output.

The "DLS Bank File" button allows selecting a DLS file for playing music. If you selected QuickTime as MIDI Output Device, you can skip selection of the DLS Bank File.

The "WVL File" button allows selecting a Wave Library file for playing music. If you selected QuickTime as MIDI Output Device, you can skip selection of the Wave Library File.

Once you've made all of your choices, click the OK button, and the main MIDIECHO window will appear.

When MIDIECHO is running, the voice limit slider may be used to adjust the "voice alert limit", or the number of notes which MSS assumes the synthesizer in use can play simultaneously. During a MIDI performance, MIDIECHO presents a continuously updated graphical display of polyphonic note activity.

When the voice alert limit is exceeded, the progress bar begins iterating, and the Total Overflow indicator below the graph will be incremented. This feature may be helpful when diagnosing note "dropout" problems that occur due to partial overflow.

When running on a slower Mac with dense MIDI traffic, MIDIECHO may exhibit undesirable tempo variations due to program overhead. If this problem occurs, the MIDI Trace checkbox can be used to disable the continuously scrolling MIDI event trace, which appears in MIDIECHO’s uppermost window.

The "All Notes Off" button can be pressed at any time to "kill" any stuck notes, which may occur while running MIDIECHO.

During playback, if a combination of XMIDI Patch Bank Select controller and MIDI Program Change number values is used to set up a timbre which cannot be found in the specified Global Timbre Library file, MIDIECHO will complain with an error message.

The "Error Beep" checkbox can be used to enable or disable the Alert Sound when note overflow occurs, or when instrument-loading errors are reported.

The "Filtering" checkbox can be marked to toggle the software synthesizer's filtering mode.

The "Reverberation" checkbox can be marked to toggle the software synthesizer's reverb mode.

MIDIECHO re-transmits incoming data on all 16 MIDI channels to the MSS driver via the AIL_send_channel_voice_message call. The program retransmits all MIDI Channel Voice messages (MIDI System Exclusive messages are retransmitted as well, but this feature should be used with caution since "timing slips" inherent in System Exclusive transmission can cause strange, misleading effects in the music.)

MIDIECHO is intended to receive normal MIDI Channel Voice data, not synthesizer-ready XMIDI data. Timing problems may occur if a dense XMIDI data stream is fed to the MIDIECHO host’s input port.

Next Topic (MIDIECHO for DOS - MIDI Data Receiver and Interpreter)

Previous Topic (MIDIECHO for Windows - MIDI Data Receiver and Interpreter)

Group: Miles Sound System Tools Reference
Related Sections: MIDIECHO for DOS - MIDI Data Receiver and Interpreter, MIDIECHO for Windows - MIDI Data Receiver and Interpreter
Related Functions: AIL_send_channel_voice_message


MIDIECHO for DOS - MIDI Data Receiver and Interpreter

Discussion

The MIDIECHO program receives incoming MIDI Channel Voice and System Exclusive messages via a Roland MPU-401-compatible MIDI interface, and sends them to a specified Miles Sound System Extended MIDI (XMIDI) driver.

MIDIECHO is a valuable resource for musicians who wish to develop music and sound-effects arrangements for MSS applications. Composers can receive immediate feedback when developing IBM-specific XMIDI compositions on a Macintosh or Atari ST-based MIDI sequencer platform, simply by connecting the host's MIDI interface to the MPU-401 interface on a "slave" PC system running MIDIECHO.

MIDIECHO has the following command-line syntax:

MIDIECHO driver.MDI  [driver.DIG]  [wavelib.WVL]  [GTL_prefix]
         [/MA:xx]    [/MI:xx]
         [/A:xx]     [/I:xx]       [/D:xx]
         [/DA:xx]    [DI:xx]       [/DD:xx]
         [/PR:xx]

where driver.MDI specifies the Miles Sound System .MDI driver to be used for playback performance, and GTL_prefix optionally indicates the pathname and filename prefix under which Yamaha or Roland MT-32 Global Timbre Library files are stored. Other optional parameters include /A:xx, /I:xx, and /D:xx, which specify the hexadecimal I/O port address, IRQ number, and DMA channel to be used by the MSS playback driver, and the /MA:xx and /MI:xx parameters which specify the address and IRQ setting of the Roland MPU401-compatible MIDI interface used to receive the incoming data. The /MA and /MI parameters are required only if the Roland interface is not addressable at its default jumper settings I/O address $330, IRQ 2. Similarly, /A and /I, and /D are necessary only if the sound adapter used for playback is configured at a non-standard I/O address or interrupt setting.

By specifying the filename of an MSS-compatible digital audio driver [driver.DIG] and a wave library [wavelib.WVL] created by the WAVELIB program, it is possible to use MIDIECHO as a composition aid for XMIDI-based sound-effect sequences or sequences which use "virtual wave synthesis" to play rhythm or melodic instrument sounds. The /DA:xx, /DI:xx, and /DD:xx parameters may be used to specify an explicit port address, interrupt number, and DMA channel for the digital driver, if necessary.

By default, the MIDIECHO program included with MSS is configured for a default pitch-bend range of +/- 2 semitones. The /PR:xx option permits other pitch-bend range values to be specified without sending MIDI RPN data, which may be useful in cases where MIDIECHO is used to compose sequences for playback on the MT-32 or other non-General MIDI platforms (including older MSS 2.0 XMIDI drivers).

While MIDIECHO is running, the + and - keys may be used to adjust the "voice alert limit," or the number of notes which MSS assumes the synthesizer in use can play simultaneously. During a MIDI performance, MIDIECHO presents a continuously-updated graphical display of polyphonic note activity. When the voice alert limit is exceeded, the portion of the bar graph to the right of the limit indicator will be shown in bright red, and the "total overflows" indicator above the graph will be incremented. This feature may be helpful when diagnosing note "dropout" problems that occur due to partial overflow.

When running on slower PC platforms with dense MIDI traffic, MIDIECHO may exhibit undesirable tempo variations due to program overhead. If this problem occurs, the T key can be used to disable the continuously scrolling MIDI event trace which appears in MIDIECHO's uppermost window.

The A key (All Notes Off) can be pressed at any time to "kill" any stuck notes which may occur while running MIDIECHO.

During playback, if a combination of XMIDI Patch Bank Select controller and MIDI Program Change number values is used to set up a timbre which cannot be found in the specified Global Timbre Library file, MIDIECHO will complain with an error message. The E key can be used to enable or disable a beep tone from the PC speaker when note overflow occurs, or when instrument-loading errors are reported.

MIDIECHO re-transmits incoming data on all 16 MIDI channels to the MSS driver via the AIL_send_channel_voice_message call. The program retransmits all MIDI Channel Voice messages. (MIDI System Exclusive messages are retransmitted as well, but this feature should be used with caution since "timing slips" inherent in System Exclusive transmission can cause strange, misleading effects in the music).

MIDIECHO is intended to receive normal MIDI Channel Voice data, not synthesizer-ready XMIDI data. Timing problems may occur if a dense XMIDI data stream (as from a Miles Sound System application or the MSS Version 2.0 CAKEPORT driver) is fed to the MIDIECHO host's input port.

Next Topic (SETSOUND - MSS Sound Configuration Utility)

Previous Topic (MIDIECHO for MacOS - MIDI Data Receiver and Interpreter)

Group: Miles Sound System Tools Reference
Related Sections: MIDIECHO for MacOS - MIDI Data Receiver and Interpreter, MIDIECHO for Windows - MIDI Data Receiver and Interpreter
Related Functions: AIL_send_channel_voice_message


SETSOUND - MSS Sound Configuration Utility

Discussion

The SETSOUND program may be distributed with MSS applications as an interactive sound driver installation and configuration utility.

SETSOUND requires no command-line parameters. It is intended to be launched after the application's end-user installation program finishes executing, as well as anytime the end user wishes to reconfigure his/her sound options after installation is complete. To avoid memory problems inherent with spawned DOS-extended executables, it is advisable to launch SETSOUND as the last step in the application's INSTALL.BAT batch file, rather than through the use of the C spawn or exec functions. Alternately, SETSOUND.C can be compiled to SETSOUND.OBJ and bound at link time to the application's end-user installation program, simply by renaming SETSOUND.C's main function.

When executed, SETSOUND presents a series of self-explanatory configuration menus. These menus allow the user to select and configure a MIDI music or digital audio driver for use by the MSS application, or to disable sound and music entirely. When either the Select and configure MIDI music driver or Select and configure digital audio driver options are chosen, SETSOUND will scan the current working directory for all MSS .DIG or .MDI drivers and present a list of these drivers to the user. All MSS drivers which are shipped with the application appear on the selection list, along with any drivers which are added to the directory by the user himself. This powerful feature ensures that an application which uses SETSOUND as its sound configuration program will not become "obsolete" as new MSS drivers are released. In accordance with RAD Game Tools's guidelines for driver installation, SETSOUND makes no attempt to install any sound drivers to determine if the supported hardware is present. Instead, DOS environment information (including the BLASTER, ULTRASND, and SNDSCAPE environment variables, as well as the contents of AUTOEXEC.BAT and CONFIG.SYS) is used to help determine which driver should be the "default" choice when the selection menu is first presented.

If the selected driver accepts I/O configuration information, SETSOUND next displays a menu offering the user the ability to Attempt to configure sound driver automatically or Skip auto-detection and configure sound driver manually. No attempt is made to auto-detect devices without the user's permission, except in cases where the driver is able to determine the correct I/O configuration without manipulating the hardware directly. (For example, the Pro Audio Spectrum drivers are able to obtain I/O information from the Media Vision device driver MVSOUND.SYS, so the configuration menu does not appear when one of these drivers is selected.) If the manual configuration option is selected, a series of menus is presented to obtain the correct I/O address, IRQ setting, and/or DMA channel assignments for the supported device. Extensive error-checking and feedback is employed throughout the installation and configuration process to help reduce sound-related technical support issues.

When a driver is successfully selected and configured, SETSOUND creates a plain-text ASCII file (called MDI.INI for MIDI music drivers or DIG.INI for digital audio drivers) which specifies the driver name, device name, and I/O settings which correspond to the user's sound hardware choice. (An example .INI file is presented in the AIL_read_INI function description. If the No MIDI music or No digital audio option is selected, any existing .INI file is deleted entirely.) The .INI files created by SETSOUND are used by the AIL_install_DIG_INI and AIL_install_MDI_INI functions to load, configure, and initialize the digital audio and/or MIDI music driver selected by the user, with no additional effort on the part of the application program.

To distribute an application with SETSOUND, you must distribute SETSOUND.EXE and its "driver list file," MSSDRVR.LST, and its Window 9x configuration utility, MSSW95.EXE. These three files should all exist in the same directory. MSSW95.EXE is spawned by SETSOUND when running under a DOS box in Windows 9x. It can also be run from the command line to display the machine's Windows 9x configuration.

MSSDRVR.LST is a text file which describes all "known" MSS drivers that existed when the current version of SETSOUND was created, and is used by SETSOUND to provide additional helpful information about each driver as the user scrolls through the selection menu. Drivers which are not listed in MSSDRVR.LST appear on the SETSOUND selection menu, but no supplemental information will be presented to the user for these drivers, and they cannot appear as the default choice in the selection menu. SETSOUND uses the current working directory for all of its file access, so all MSS drivers delivered with an application must be copied into a working subdirectory on the user's hard disk during installation, along with MSSDRVR.LST and (preferably) SETSOUND.EXE itself. The DIG.INI and MDI.INI files will be created and stored in this subdirectory as well. Whether SETSOUND is actually copied to the user's sound directory or left on the application's distribution CD, please be sure that SETSOUND can be executed by the end user at any time after installation! Otherwise, the user will be "stuck" with his/her original sound configuration choice, with no alternative but to re-install the application when upgrading or changing sound hardware.

The SETSOUND.EXE distributed from RAD Game Tools was bound with the Causeway DOS extender. This means that unless you rebuild SETSOUND.EXE, you don't need to distribute DOS4GW.EXE. Note that if you rebuild SETSOUND.EXE, you must either link it with an .EXE-bound DOS extender such as Causeway, DOS/4GW Professional or FlashTek X/32, or make sure that a copy of the DOS extender (DOS4GW.EXE) is available in the current path at the time SETSOUND is executed.

Applications which employ only one type of audio support (either digital audio or MIDI music) should be shipped with drivers of only the required type (.DIG or .MDI). SETSOUND will automatically reconfigure its menus to omit all references to the "unsupported" audio format.

Internationalization of the SETSOUND program is possible; however, the interactive nature of its text menu system requires modifications to text strings within SETSOUND.C itself. The file MSSDRVR.LST may be easily modified to support other languages, but it does not contain all of the text strings used by SETSOUND. Contact RAD Game Tools for information on how to modify the specially-formatted text strings used by SETSOUND to present its menus and dialog boxes.

Next Topic (GLIB - Extended MIDI (XMIDI) Global Timbre Librarian)

Previous Topic (MIDIECHO for DOS - MIDI Data Receiver and Interpreter)

Group: Miles Sound System Tools Reference
Related Sections: Distributing Miles with DOS Applications
Related Functions: AIL_install_DIG_INI, AIL_install_MDI_INI, AIL_read_INI


GLIB - Extended MIDI (XMIDI) Global Timbre Librarian

Discussion

The GLIB program creates Global Timbre Library files for use by Miles Sound System Extended MIDI (XMIDI) driver applications.

The Global Timbre Library, or GTL, is the set of timbres, or sound description data for musical instruments or sound effects, which are intended for use by a given synthesizer during the course of an entire Miles Sound System application. Each supported synthesizer may have its own timbre data format, so an application may need as many GTL files as it has XMIDI drivers. Many synthesizers (such as the Ad Lib) contain no built-in timbres, and thus require at least a small GTL file in order to make any sounds at all. Others, such as the Roland MT-32, contain a number of built-in timbres, and do not require GTL support unless the musician wishes to supplement the built-in timbres with "custom" timbres created with a third-party editor program.

GLIB is responsible for creating each Global Timbre Library file according to instructions in a standard ASCII catalog file, or "catfile." The catfile is created by a musician or programmer who is responsible for deciding how some or all of the 128 possible MIDI Program Change ("Patch") numbers are mapped to as many as 16,000 possible timbres of both the built-in and custom types, at various points during the application's execution. A single catfile may serve as the "script" for every Global Timbre Library file used by an application, but the usual practice is to maintain a separate catfile for each individual synthesizer's GTL file.

Each timbre specification in the GLIB catalog file consists of an assignment statement of the form.

timbre(bank,patch) = ...

In an assignment statement, the '...' expression on the right side of the assignment statement (or rvalue) tells GLIB where to find the source data for the timbre (in an Ad Lib Instrument Maker bankfile, for example). The timbre( ) expression on the left (or lvalue) specifies the destination "address" of the timbre in the Global Timbre Library file being created. This "address" consists of a timbre bank number and a patch (MIDI Program Change number) mapping for the timbre. A musician who is composing a MIDI sequence for use with an MSS XMIDI driver may "request" that a custom timbre be associated with a particular patch during playback, simply by prefixing each MIDI Program Change message in the sequence with an XMIDI Patch Bank Select controller (114) which specifies the bank number under which the desired timbre for the patch was stored in the Global Timbre Library file. For each synthesizer, only one timbre may be mapped to a particular patch at any given time.

The nature of the '...' rvalue expression depends on the GTL file's target synthesizer. The following rvalue expressions are currently supported by GLIB:

BNK_inst(string,num): Refers to the name of an Ad Lib instrument to be found in an Ad Lib Instrument Maker bankfile which was previously specified with a BNK_file( ) expression (see below). num normally specifies the number of semitones by which to transpose notes played with the instrument. (This value is added to any transposition value specified with the Ad Lib Gold Instrument Maker.) If the timbre is to be played in MIDI channel 10 (to emulate a Roland MT-32 rhythm key), num specifies the MIDI note number corresponding to the pitch at which the instrument should sound. In such a case, the bank number specified in the lvalue must be 127, while the patch number specifies the MIDI key number which causes the instrument to be played.

MTB_file("filename"): Refers to the name of a Big Noise MT-32 Editor/Librarian file containing a complete bank of 64 Roland MT-32 timbres. The 64 timbres will be mapped to 64 sequential patches beginning at the patch number given in the timbre( ) lvalue expression. (If this sequential mapping causes any timbre's patch number to exceed 127, the patch bank number is incremented at that point and the patch number itself is incremented modulo 128.) Note that only the timbres, or "tones," in the file are used by GLIB; the "bank timbre patch change" and "rhythm key table" information in the file is ignored.

BIN_file("filename"): Refers to the name of a binary file containing a single timbre image in the target Miles Sound System driver's native timbre format. This "generic" expression is useful in cases where the application designer wishes to use a proprietary editor with its own timbre file format, but is not otherwise needed.

In addition to timbre assignment statements, GLIB recognizes two "declarative" expressions:

outfile("filename"): Specifies the name of a Global Timbre Library to create. An outfile( ) specification must appear in the catfile before any timbres are assigned to the outfile. When this statement is encountered, any GTL file being created by a previous outfile( ) statement is closed and saved to disk.

BNK_file("filename"): Specifies the Ad Lib Instrument Maker bankfile from which subsequent BNK_inst( ) statements should retrieve timbres for inclusion in the Global Timbre Library file. The Ad Lib Instrument Maker program (version 1.5 or greater) is used to create the .BNK "source file" format for all Yamaha YM3812-based adapters, including the Ad Lib, Sound Blaster, Sound Blaster Pro, Pro Audio Spectrum, Thunderboard, and others.

Beginning with GLIB version 1.02, bankfiles from the Ad Lib Gold Instrument Maker program may be used interchangeably with those created by the original Ad Lib Instrument Maker. The Ad Lib Gold Instrument Maker may be used to create 4-operator timbres for the Ad Lib Gold card and other sound adapters based on the Yamaha YMF262 (OPL3) integrated circuit, as well as 2-operator timbres for standard YM3812-compatible adapters. To guard against inadvertent use of 4-operator timbres in GTL files intended for use with YM3812 drivers, GLIB will issue a warning message if any BNK_inst( ) statement assigns a 4-operator timbre to an output file whose suffix is ".AD".

All characters appearing on a line after a semicolon are considered to be comments, and ignored. Blank lines are also acceptable.

The catalog file used to create a Global Timbre Library is of extreme importance in determining how well a given XMIDI sequence will sound when "tweaked" for optimum Ad Lib playback quality. Supplied with the Miles Sound System is SAMPLE.CAT, a sample GLIB catalog file which creates an Ad Lib-compatible Global Timbre Library file, and SAMPLE.BNK, an Ad Lib Instrument Maker bankfile containing approximately 200 "canned" instruments supplied with the Ad Lib and Sound Blaster developer kits. The sample Ad Lib GTL file SAMPLE.AD was created by the following command:

GLIB sample.cat

The created SAMPLE.AD should be used only for development, testing, and experimental purposes, as its instruments are not "adjusted" with the Instrument Maker program to emulate the Roland synthesizer faithfully in important areas such as octave register, envelope timing, relative volume level, and general tonal quality. For shipping purposes, you should usually use The Fat Man's FM patches that are supplied in the /REDIST/DOS directory.

As an example of a GLIB catalog file, SAMPLE.CAT is reproduced here in its entirety.

;
;SAMPLE.CAT
;Global Timbre Library assignments for sample MSS V2.0 applications
;
;Usage: GLIB sample.cat
;
outfile("sample.ad")            ;create Ad Lib Global Timbre Library
BNK_file("sample.bnk")          ;name of Ad Lib Instrument Maker bankfile
;
;Bank 0: Melodic instruments to emulate Roland MT-32 built-in timbres
;
timbre(0,0) = BNK_inst("piano1",0)             ;Acou Piano 1
timbre(0,1) = BNK_inst("piano3",0)             ;Acou Piano 2
timbre(0,2) = BNK_inst("piano4",0)             ;Acou Piano 3
timbre(0,3) = BNK_inst("elpiano1",0)           ;Elec Piano 1
timbre(0,4) = BNK_inst("elpiano2",0)           ;Elec Piano 2
timbre(0,5) = BNK_inst("elpiano1",0)           ;Elec Piano 3
timbre(0,6) = BNK_inst("pianof",0)             ;Elec Piano 4
timbre(0,7) = BNK_inst("piano1",0)             ;Honkytonk
timbre(0,8) = BNK_inst("organ2",0)             ;Elec Org 1
timbre(0,9) = BNK_inst("organ1",0)             ;Elec Org 2
timbre(0,10) = BNK_inst("organ1",0)            ;Elec Org 3
timbre(0,11) = BNK_inst("organ4",0)            ;Elec Org 4
timbre(0,12) = BNK_inst("pipes",0)             ;Pipe Org 1
timbre(0,13) = BNK_inst("pipes",0)             ;Pipe Org 2
timbre(0,14) = BNK_inst("pipes",0)             ;Pipe Org 3
timbre(0,15) = BNK_inst("accordn",0)           ;Accordion
timbre(0,16) = BNK_inst("harpsi4",0)           ;Harpsi 1
timbre(0,17) = BNK_inst("harpsi4",0)           ;Harpsi 2
timbre(0,18) = BNK_inst("harpsi4",0)           ;Harpsi 3
timbre(0,19) = BNK_inst("elclav2",0)           ;Clavi 1
timbre(0,20) = BNK_inst("elclav2",0)           ;Clavi 2
timbre(0,21) = BNK_inst("elclav2",0)           ;Clavi 3
timbre(0,22) = BNK_inst("celesta",0)           ;Celesta 1
timbre(0,23) = BNK_inst("celesta",0)           ;Celesta 2
timbre(0,24) = BNK_inst("sftbrss1",0)          ;Syn Brass 1
timbre(0,25) = BNK_inst("sftbrss1",0)          ;Syn Brass 2
timbre(0,26) = BNK_inst("sftbrss1",0)          ;Syn Brass 3
timbre(0,27) = BNK_inst("sftbrss1",0)          ;Syn Brass 4
timbre(0,28) = BNK_inst("bass2",0)             ;Syn Bass 1
timbre(0,29) = BNK_inst("bass2",0)             ;Syn Bass 2
timbre(0,30) = BNK_inst("bass2",0)             ;Syn Bass 3
timbre(0,31) = BNK_inst("bass2",0)             ;Syn Bass 4
timbre(0,32) = BNK_inst("fantapan",0)          ;Fantasy
timbre(0,33) = BNK_inst("mars",0)              ;Harmo Pan
timbre(0,34) = BNK_inst("syn1",0)              ;Chorale
timbre(0,35) = BNK_inst("tincan1",0)           ;Glasses
timbre(0,36) = BNK_inst("mars",0)              ;Soundtrack
timbre(0,37) = BNK_inst("moon",0)              ;Atmosphere
timbre(0,38) = BNK_inst("trainbel",0)          ;Warm Bell
timbre(0,39) = BNK_inst("synbass1",0)          ;Funny Vox
timbre(0,40) = BNK_inst("bells",0)             ;Echo Bell
timbre(0,41) = BNK_inst("bells",0)             ;Ice Rain
timbre(0,42) = BNK_inst("oboe1",0)             ;Oboe 2001
timbre(0,43) = BNK_inst("bass1",0)             ;Echo Pan
timbre(0,44) = BNK_inst("bass2",0)             ;Doctor Solo
timbre(0,45) = BNK_inst("bass2",0)             ;Schooldaze
timbre(0,46) = BNK_inst("javaican",0)          ;Bellsinger
timbre(0,47) = BNK_inst("csynth",0)            ;Square Wave
timbre(0,48) = BNK_inst("strings1",0)          ;Str Sect 1
timbre(0,49) = BNK_inst("strnlong",0)          ;Str Sect 2
timbre(0,50) = BNK_inst("strings1",0)          ;Str Sect 3
timbre(0,51) = BNK_inst("koto1",0)             ;Pizzicato
timbre(0,52) = BNK_inst("violin",0)            ;Violin 1
timbre(0,53) = BNK_inst("violin1",0)           ;Violin 2
timbre(0,54) = BNK_inst("violin",0)            ;Cello 1
timbre(0,55) = BNK_inst("cello",0)             ;Cello 2
timbre(0,56) = BNK_inst("contrab",0)           ;Contrabass
timbre(0,57) = BNK_inst("harp1",0)             ;Harp 1
timbre(0,58) = BNK_inst("harp",0)              ;Harp 2
timbre(0,59) = BNK_inst("guitar1",0)           ;Guitar 1
timbre(0,60) = BNK_inst("guitar1",0)           ;Guitar 2
timbre(0,61) = BNK_inst("elguit2",0)           ;Elec Gtr 1
timbre(0,62) = BNK_inst("elguit1",0)           ;Elec Gtr 2
timbre(0,63) = BNK_inst("sitar1",0)            ;Sitar
timbre(0,64) = BNK_inst("bbass",0)             ;Acou Bass 1
timbre(0,65) = BNK_inst("bass2",0)             ;Acou Bass 2
timbre(0,66) = BNK_inst("bass2",0)             ;Elec Bass 1
timbre(0,67) = BNK_inst("bass2",0)             ;Elec Bass 2
timbre(0,68) = BNK_inst("bbass",0)             ;Slap Bass 1
timbre(0,69) = BNK_inst("bbass",0)             ;Slap Bass 2
timbre(0,70) = BNK_inst("bass1",0)             ;Fretless 1
timbre(0,71) = BNK_inst("bass1",0)             ;Fretless 2
timbre(0,72) = BNK_inst("flute1",0)            ;Flute 1
timbre(0,73) = BNK_inst("flute1",0)            ;Flute 2
timbre(0,74) = BNK_inst("flute1",0)            ;Piccolo 1
timbre(0,75) = BNK_inst("flute1",0)            ;Piccolo 2
timbre(0,76) = BNK_inst("flute2",0)            ;Recorder
timbre(0,77) = BNK_inst("flute2",0)            ;Pan Pipes
timbre(0,78) = BNK_inst("sax1",0)              ;Sax 1
timbre(0,79) = BNK_inst("sax1",0)              ;Sax 2
timbre(0,80) = BNK_inst("sax1",0)              ;Sax 3
timbre(0,81) = BNK_inst("softsax",0)           ;Sax 4
timbre(0,82) = BNK_inst("clar1",0)             ;Clarinet 1
timbre(0,83) = BNK_inst("clarinet",0)          ;Clarinet 2
timbre(0,84) = BNK_inst("oboe",0)              ;Oboe
timbre(0,85) = BNK_inst("oboe",0)              ;Engl Horn
timbre(0,86) = BNK_inst("bassoon",0)           ;Bassoon
timbre(0,87) = BNK_inst("harmonca",0)          ;Harmonica
timbre(0,88) = BNK_inst("trumpet4",0)          ;Trumpet 1
timbre(0,89) = BNK_inst("trumpet4",0)          ;Trumpet 2
timbre(0,90) = BNK_inst("tromb2",0)            ;Trombone 1
timbre(0,91) = BNK_inst("tromb1",0)            ;Trombone 2
timbre(0,92) = BNK_inst("frhorn1",0)           ;Fr Horn 1
timbre(0,93) = BNK_inst("frhorn2",0)           ;Fr Horn 2
timbre(0,94) = BNK_inst("tuba1",0)             ;Tuba
timbre(0,95) = BNK_inst("brass1",0)            ;Brs Sect 1
timbre(0,96) = BNK_inst("brass2",0)            ;Brs Sect 2
timbre(0,97) = BNK_inst("vibra2",0)            ;Vibe 1
timbre(0,98) = BNK_inst("vibra3",0)            ;Vibe 2
timbre(0,99) = BNK_inst("marimba",0)           ;Syn Mallet
timbre(0,100) = BNK_inst("belshort",0)         ;Windbell
timbre(0,101) = BNK_inst("belshort",0)         ;Glock
timbre(0,102) = BNK_inst("belshort",0)         ;Tube Bell
timbre(0,103) = BNK_inst("xylofone",0)         ;Xylophone
timbre(0,104) = BNK_inst("marimba",0)          ;Marimba
timbre(0,105) = BNK_inst("koto1",0)            ;Koto
timbre(0,106) = BNK_inst("fstrp2",0)           ;Sho
timbre(0,107) = BNK_inst("flute",0)            ;Shakuhachi
timbre(0,108) = BNK_inst("flute",0)            ;Whistle 1
timbre(0,109) = BNK_inst("flute",0)            ;Whistle 2
timbre(0,110) = BNK_inst("flute2",0)           ;Bottleblow
timbre(0,111) = BNK_inst("flute2",0)           ;Breathpipe
timbre(0,112) = BNK_inst("bdrum3",0)           ;Timpani
timbre(0,113) = BNK_inst("tom",0)              ;Melodic Tom
timbre(0,114) = BNK_inst("sdrum2",0)           ;Deep Snare
timbre(0,115) = BNK_inst("synsnr1",0)          ;Elec Perc 1
timbre(0,116) = BNK_inst("synsnr1",0)          ;Elec Perc 2
timbre(0,117) = BNK_inst("synsnr2",0)          ;Taiko
timbre(0,118) = BNK_inst("synsnr2",0)          ;Taiko Rim
timbre(0,119) = BNK_inst("cymbal",0)           ;Cymbal
timbre(0,120) = BNK_inst("shppizz",0)          ;Castanets
timbre(0,121) = BNK_inst("triangle",0)         ;Triangle
timbre(0,122) = BNK_inst("synbass4",0)         ;Orche Hit
timbre(0,123) = BNK_inst("phone1",0)           ;Telephone
timbre(0,124) = BNK_inst("chirp",0)            ;Bird Tweet
timbre(0,125) = BNK_inst("mars",0)             ;One Note Jam
timbre(0,126) = BNK_inst("bells",0)            ;Water Bells
timbre(0,127) = BNK_inst("meri",0)             ;Jungle Tune
;
;Rhythm key assignments (to Ad Lib melodic instruments)
;
;Played in channel 10 to emulate built-in Roland MT-32 rhythm sounds
;
;(Bank 127 reserved for use with "rhythm" emulation instruments)
;
timbre(127,35) = BNK_inst("bdrum",41)          ;Acou BD
timbre(127,36) = BNK_inst("bdrum",41)          ;Acou BD
timbre(127,37) = BNK_inst("tom",55)            ;Rim Shot
timbre(127,38) = BNK_inst("snare2",60)         ;Acou SD
timbre(127,39) = BNK_inst("snare2",60)         ;Hand Clap
timbre(127,40) = BNK_inst("snare2",60)         ;Elec SD
timbre(127,41) = BNK_inst("tom",41)            ;Acou Low Tom
timbre(127,42) = BNK_inst("clsdhi",84)         ;Clsd Hi Hat
timbre(127,43) = BNK_inst("tom",41)            ;Acou Low Tom
timbre(127,44) = BNK_inst("bcymbal",84)        ;Open Hi Hat 2
timbre(127,45) = BNK_inst("tom",48)            ;Acou Mid Tom
timbre(127,46) = BNK_inst("bcymbal",84)        ;Open Hi Hat 1
timbre(127,47) = BNK_inst("tom",48)            ;Acou Mid Tom
timbre(127,48) = BNK_inst("tom",55)            ;Acou Hi Tom
timbre(127,49) = BNK_inst("cymbal3",72)        ;Crash Cym
timbre(127,50) = BNK_inst("tom",55)            ;Acou Hi Tom
timbre(127,51) = BNK_inst("bcymbal",84)        ;Ride Cym
timbre(127,54) = BNK_inst("bcymbal",84)        ;Tambourine
timbre(127,56) = BNK_inst("tom",48)            ;Cowbell
timbre(127,60) = BNK_inst("tom",55)            ;High Bongo
timbre(127,61) = BNK_inst("tom",41)            ;Low Bongo
timbre(127,62) = BNK_inst("tom",55)            ;Mt High Conga
timbre(127,63) = BNK_inst("tom",55)            ;High Conga
timbre(127,64) = BNK_inst("tom",48)            ;Low Conga
timbre(127,65) = BNK_inst("tom",55)            ;High Timbale
timbre(127,66) = BNK_inst("tom",41)            ;Low Timbale
timbre(127,67) = BNK_inst("snare2",60)         ;High Agogo
timbre(127,68) = BNK_inst("snare2",48)         ;Low Agogo
timbre(127,69) = BNK_inst("bcymbal",84)        ;Cabasa
timbre(127,70) = BNK_inst("bcymbal",84)        ;Maracas
timbre(127,71) = BNK_inst("bcymbal",84)        ;Smba Whis S
timbre(127,72) = BNK_inst("bcymbal",84)        ;Smba Whis L
timbre(127,73) = BNK_inst("bcymbal",84)        ;Quijada
timbre(127,75) = BNK_inst("bcymbal",84)        ;Claves

Next Topic (CLAD - Creative Labs and Ad Lib (TM) Converter)

Previous Topic (SETSOUND - MSS Sound Configuration Utility)

Group: Miles Sound System Tools Reference


CLAD - Creative Labs and Ad Lib (TM) Converter

Discussion

The CLAD program translates instrument data between the Ad Lib and Creative Labs (Sound Blaster) native file formats. .INS and .SBI files are used by the Ad Lib and Creative Labs voice editing tools, respectively.

CLAD has the following command-line syntax:

CLAD < infile.ins | infile.sbi > < outfile.ins | outfile.sbi >

where infile represents the instrument file (in either Ad Lib (.INS) or Sound Blaster (.SBI) format) to translate, and outfile represents the file to be created in the new format.

The use of the .INS and .SBI file suffixes is mandatory.

INS2SBI, a similar program which accompanies the Sound Blaster Developer Kit, can also perform a one-way instrument file translation from the Ad Lib format to the Sound Blaster format. However, INS2SBI contains several bugs; CLAD should be used for this purpose instead.

Next Topic (MIDILOG - MIDI File Event Filter)

Previous Topic (GLIB - Extended MIDI (XMIDI) Global Timbre Librarian)

Group: Miles Sound System Tools Reference


MIDILOG - MIDI File Event Filter

Discussion

The MIDILOG program strips any non-standard headers and trailers from a Standard MIDI file, and optionally translates certain MIDI events in the file.

The ability to translate MIDI events makes MIDILOG a powerful tool when dealing with sequencer programs that do not allow certain events to be embedded in a MIDI file, but which are capable of recording other types of events which may be replaced later with the events originally desired by the musician or programmer.

MIDILOG has the following command-line syntax:

MIDILOG infile outfile [logfile]

where infile refers to the original MIDI file to be translated, outfile specifies the MIDI output file, and logfile specifies an optional ASCII text file containing a list of event translation rules to apply to the infile's MIDI events while copying them to the outfile.

An event translation rule consists of two expressions separated by an '=' sign. Both expressions represent MIDI events. During the MIDI file translation process, MIDILOG compares each event in the infile with each event translation rule's lvalue, or the expression on the left side of its '=' sign. If no match is found, the infile's event is written, unchanged, to the outfile. However, if the event matches one of the logfile's lvalues, the event on the right side of the same event translation rule's '=' sign, called the rvalue, is written to the outfile instead.

Up to 128 event translation rules may appear in each logfile. Each expression used in an event translation rule must take one of the following forms. (Terms in [] brackets may appear zero or more times).

event( [val,] ): Any MIDI event.

meta_event( type, [val,] ): A MIDI meta-event of type /type/, optionally containing zero or more bytes of associated data. For example, meta_event(1, "Test") is identical to event($FF,$01,$04, "Test").

MT32_sysex_event( addr_MSB, addr, addr_LSB, data, [data,]): A type DT1 System Exclusive event capable of addressing Roland MT-32-compatible synthesizers. No nibble masks or wildcards (see below) may be used. For example, MT32_sysex_event($20,$00,$00, "This is a test"), when written to a MIDI file as an rvalue, will cause the string 'This is a test' to appear on the MT-32's front-panel LCD display when the file is performed.

The values used within each expression must conform to the following rules:

$nn: A single hexadecimal byte, which may be 1 or 2 digits in length. The letter 'x' may be used to mask one of the nibbles in the byte, causing that nibble to be disregarded in event comparisons. The value of the last nibble masked in a rule's lvalue is restored to any masked nibbles in the rvalue, which is useful for preserving channel nibbles in replaced MIDI status bytes. Character case is not meaningful. Examples: $4, $69, $Bx.

nnn: A single decimal byte, which may range from 1 to 3 digits in length. Examples: 4, 105, 176.

'...' / "...": A string literal value. Either apostrophes or quotation marks may be used. Examples: 'Test', "Test".

? or $xx: Wildcard decimal byte value. The entire byte is masked (disregarded in event comparisons). The value of the last byte masked in a rule's lvalue is restored to any masked bytes in the rvalue, which is useful for preserving data bytes in replaced MIDI events.

Commas must be used to separate values within expressions. Up to 16 bytes may appear in each rule's lvalue expression, while as many as 128 bytes may appear in each rvalue expression.

All characters appearing on a line after a semicolon (';') are considered to be comments, and are ignored. All characters appearing before an equal sign ('=') are considered to be part of the rule's lvalue expression; all characters appearing after an equal sign are considered to be part of its rvalue expression. For example, the line:

event($Bx,120,0) = meta_event($01, "Test")   ;Control Change #120

contains a valid event translation rule which will trap infile events that set Controller 120 in any MIDI channel to a value of 0, replacing them in the outfile with Text meta-events containing the string "Test".

An empty rvalue in a rule (such as event( )) may be used to completely remove events which match the rule's lvalue. When an event is removed in this manner, however, its delta-time prefix is removed as well. This may cause loss of synchronization between tracks. To avoid this problem, it is best to replace the undesired event with an unrecognized Control Change or similar event, rather than simply preventing it from appearing in the outfile.

It is impossible to use MIDILOG's advanced features effectively without a good understanding of MIDI events and the Standard MIDI File specification. However, an in-depth examination of these subjects is beyond the scope of this documentation. To learn more about all aspects of MIDI, refer to a good general-purpose reference such as De Furia and Scacciaferro's MIDI Programmer's Handbook.

Below is a sample logfile for use with MIDILOG.

;
;SYSTEST.LOG
;Sample event translation logfile - turns SEQ.MID into APP.MID
;
;Usage: midilog seq.mid app.mid systest.log
;
     event($Bx,118,0) = meta_event($01, "Second measure")
     event($Bx,119,1) = meta_event($02, "Copyright (C) 1991")
     event($Bx,120,?) = meta_event($7E,?)                 ;Generic meta
     event($Bx,117,?) = event($F0,$43,$12,$00,$07,$F7)    ;Generic sysex
     event($Bx,116,?) = MT32_sysex_event($10,$00,$01,1,7,7) ;MT-32 reverb

Next Topic (MIDIREC- Standard MIDI File Recorder)

Previous Topic (CLAD - Creative Labs and Ad Lib (TM) Converter)

Group: Miles Sound System Tools Reference


MIDIREC- Standard MIDI File Recorder

Discussion

The MIDIREC program receives incoming MIDI Channel Voice and System Exclusive messages via a Roland MPU-401-compatible MIDI interface, and records them to a Standard MIDI Format 0 file.

MIDIREC has the following command-line syntax:

MIDIREC filename [/MA:xx] [/MI:xx]

filename indicates the name of the Standard MIDI Format 0 file to create. Optional parameters include /MA:xx and /MI:xx, which specify the hexadecimal I/O port address and IRQ number, respectively, of the Roland-compatible MIDI interface used to receive the incoming data.

MIDIREC's advantage over many MIDI sequencers such as Cakewalk is its ability to record System Exclusive message transmissions, in addition to conventional MIDI Channel Voice messages. When used in conjunction with the Miles Sound Studio's intelligent Roland MT-32 System Exclusive disassembly feature, MIDIREC is a valuable diagnostic tool for the examination of a MIDI application's output stream, whether or not the stream originated from a Miles Sound System driver.

The MIDIREC output file conforms to the standards for a Format 0 MIDI file, and is recorded as though it is being played in 4/4 time with a division of 120 delta-time ticks per quarter note and a tempo of 500,000 microseconds per quarter note. If necessary, the file may be imported into a sequencer to adjust these parameters, but care should be taken not to inadvertently "lose" System Exclusive information in the process.

Next Topic (WAVELIB - Wave Synthesizer Librarian)

Previous Topic (MIDILOG - MIDI File Event Filter)

Group: Miles Sound System Tools Reference


WAVELIB - Wave Synthesizer Librarian

Discussion

This utility should now be considered obsolete - all future digital synthesis should be performed with the new DLS functions! WAVELIB only exists for backwards compatibility now.

The WAVELIB program extracts raw PCM sample data from standard Creative Labs Sound Blaster Voice Editor-compatible .VOC files, as well as Microsoft Windows-compatible .WAV files, and stores it in a wave library file for use with XMIDI-sequenced digital sound effects.

WAVELIB has the following command-line syntax:

WAVELIB list_file.TXT

The list file is an unformatted ASCII text file which contains a list of .VOC, .WAV, and/or raw audio data files which are assigned to MIDI Program Change numbers and XMIDI Patch Bank Select values. Upon installing a wave library file with the AIL_create_wave_synthesizer function, the instruments stored in the wave library will replace or add to the default set of MIDI instruments associated with the XMIDI driver in use. MIDI Program Change (and optionally XMIDI Patch Bank Select) messages in a sequence may be used to select a digital sound effect for triggering with subsequent MIDI Note On/Note Off messages. Pitch Bend, Panpot, and Part Volume messages are also emulated by the digital sound-effects system. Rhythm instruments assigned to XMIDI Patch Bank 127 may be mapped to various MIDI note numbers in channel 10, while melodic instruments assigned to other XMIDI Patch Banks (or none at all) are played normally in the other channels.

.VOC and .WAV files specified in the list file must fit into available EMS/XMS memory, and should not contain "silence packing" blocks, infinite repeat loops, or voice blocks with varying sample rates or compression types. IMA ADPCM compression is not supported.

During the conversion process, "repeat blocks" in .VOC files are expanded into multiple instances of the repeated voice data blocks. The "extended block" type introduced with the Sound Blaster Pro developer kit is also supported by WAVELIB, as is the new 16-bit voice block type introduced with the Sound Blaster 16.

The following is a copy of the WAVEDEMO.TXT example list file which is provided with the MSS. Options supported by WAVELIB in this release include the features mentioned above. Later releases of WAVELIB may support additional options; check the WAVEDEMO.TXT file provided with subsequent releases for information on any new features or options.

;*****************************************************************************
;**                                                                         **
;** Example file list for software wave triggers                            **
;**                                                                         **
;** This file describes a set of digital audio samples to be played by the  **
;** digital audio system in response to MIDI Note On/Off events.            **
;**                                                                         **
;**                                                                         **
;**                                                                         **
;** At the beginning of the list file, use:                                 **
;**                                                                         **
;**    F=??? to declare the name of the wave library file to create         **
;**                                                                         **
;**          ??? represents a DOS filename in quotes; e.g. "demo.wvl"       **
;**                                                                         **
;**                                                                         **
;**                                                                         **
;** For each digital audio sample to be played as a MIDI instrument, use:   **
;**                                                                         **
;**    B=nnn to set XMIDI Patch Bank Select (controller 114) value          **
;**                                                                         **
;**          Set this value to 0 if your sequences do not contain Patch     **
;**          Bank Select controllers                                        **
;**                                                                         **
;**    P=nnn to set MIDI patch # for sound (B=0-126) or MIDI trigger key #  **
;**          for rhythm sound (B=127 only)                                  **
;**                                                                         **
;**    R=nnn to set root MIDI note # for sound (B=0-126)                    **
;**                                                                         **
;**          For example, middle C (C5) is note number 60; if R= parameter  **
;**          is not used, a value of 60 is assumed                          **
;**                                                                         **
;**          The R= parameter is not needed for bank 127 (rhythm) sounds    **
;**                                                                         **
;**                                                                         **
;**                                                                         **
;** The following parameters are used with raw data files ONLY:             **
;**                                                                         **
;**    S=nnn to set sample playback rate (11025, 22050, etc.)               **
;**                                                                         **
;**    C=nnn to set # of digital channels (1=mono, 2=stereo)                **
;**                                                                         **
;**    W=nnn to set sample word size (8 or 16 bits)                         **
;**                                                                         **
;**                                                                         **
;**                                                                         **
;** All .VOC/.WAV/raw source filenames must be enclosed in quotes ("")      **
;**                                                                         **
;** Up to 512 samples may appear in one list file.  Lines which begin with  **
;** semicolons are treated as comments.  Blank lines are permitted.         **
;**                                                                         **
;*****************************************************************************
F="demo.wvl"
B=127  , P=60  , S=44100 , C=1 , W=8 , "..\media\welcome.raw"
B=127  , P=61  , S=44100 , C=1 , W=8 , "..\media\flyby.raw"
B=127  , P=62  , S=44100 , C=1 , W=8 , "..\media\she_bop.raw"
B=127  , P=63  , S=44100 , C=1 , W=8 , "..\media\charge.raw"
B=127  , P=64  , S=44100 , C=1 , W=8 , "..\media\klaxon.raw"
B=127  , P=65  , S=44100 , C=1 , W=8 , "..\media\guitar.raw"
B=127  , P=66  , S=44100 , C=1 , W=8 , "..\media\thriller.raw"
B=127  , P=67  , S=44100 , C=1 , W=8 , "..\media\nena.raw"
B=127  , P=68  ,                       "..\media\glass.wav"

Previous Topic (MIDIREC- Standard MIDI File Recorder)

Group: Miles Sound System Tools Reference
Related Functions: AIL_create_wave_synthesizer


Extended MIDI Technical Reference

Discussion

XMIDI is both an extension to MIDI as well as a more convenient playback file format.

XMIDI provides a number of additional MIDI-style Control Change messages which greatly extend the range of composition and arrangement options available to the musician and application programmer.

This chapter contains descriptions of all of the Extended MIDI Control Change messages available in the current Miles Sound System release, together with explanations of their uses in XMIDI sequences, as well as descriptions of the XMIDI file formats that MSS uses.

Extended MIDI Technical Reference
XMIDI Channel Mute (107)
XMIDI Callback Prefix (108)
XMIDI Sequence Branch (109)
XMIDI Channel Lock (110)
XMIDI Channel Lock Protect (111)
XMIDI Voice Protect (112)
XMIDI Timbre Protect (113)
XMIDI Patch Bank Select (114)
XMIDI Indirect Controller Prefix (115)
XMIDI For Loop Controller (116)
XMIDI Next-Break Loop Controller (117)
XMIDI Clear Beat-Bar Count (118)
XMIDI Callback Trigger (119)
XMIDI Sequence Branch Index (120)
Extended MIDI IFF (.XMI) Structure
Extended MIDI Global Timbre Library File Format


XMIDI Channel Mute (107)

Discussion

The XMIDI Channel Mute controller (107), if set to a value greater than or equal to 64, inhibits all further MIDI Note On messages in a given channel. To resume normal MIDI Note On transmission, a Channel Mute controller with a value of less than 64 should be transmitted.

This controller may be used in combination with the XMIDI Callback Prefix (108) or Indirect Controller Prefix (115) controllers to allow the application program to mute and unmute MIDI tracks selectively. It may also be transmitted at any time via the AIL_send_channel_voice_message function.

MIDI Note Off messages are not blocked by Channel Mute. This prevents "stuck notes" which could otherwise occur if a Channel Mute controller is received while one or more notes are active in the channel. Additionally, MIDI controller, Program Change, pitch bend, system exclusive, and other messages are unaffected.

Next Topic (XMIDI Callback Prefix (108))

Group: Extended MIDI Technical Reference
Related Functions: AIL_send_channel_voice_message


XMIDI Callback Prefix (108)

Discussion

This controller specifies that the next Control Change message encountered in this channel should obtain its value from the return value of an application callback function. For more information on the Callback Prefix controller, see the AIL_register_prefix_callback function description.

Next Topic (XMIDI Sequence Branch (109))

Previous Topic (XMIDI Channel Mute (107))

Group: Extended MIDI Technical Reference
Related Functions: AIL_register_prefix_callback


XMIDI Sequence Branch (109)

Discussion

This controller forces an immediate and unconditional branch to the location of a Sequence Branch Index (120) controller with the same controller value. Its action is identical to that of the AIL_branch_index function. For more information on XMIDI sequence branching, refer to the AIL_branch_index function description and the MDI_ALLOW_LOOP_BRANCHING preference description. Also see the description of the Sequence Branch Index controller below.

Next Topic (XMIDI Channel Lock (110))

Previous Topic (XMIDI Callback Prefix (108))

Group: Extended MIDI Technical Reference
Related Functions: AIL_branch_index
Related Basic Types: MILES_PREFERENCES


XMIDI Channel Lock (110)

Discussion

< 64: Release previously locked channel and restore default channel number mapping

>= 64: Seize ("lock") an unlocked, unprotected physical MIDI channel (2-9) for assignment to this logical channel # (11-16)

The Channel Lock controller is one of the more powerful Extended MIDI controllers. Channel locking allows the XMIDI drivers to play multiple XMIDI sequences simultaneously, which in turn permits the creation of impressive sound effects and musical "mixes."

When used with a value greater than or equal to 64, the Channel Lock controller attempts to seize, or "lock," the highest MIDI channel number recognized by the driver's supported synthesizer which has the fewest actively playing notes. Channels which are already locked are immune to relocking. Channels which have been "protected" against locking by use of the XMIDI Channel Lock Protect controller (111), are immune to seizure unless no other unlocked channels are available.

After a MIDI channel has been successfully locked, the driver maps the locked channel onto the MIDI channel in which the Channel Lock controller itself appeared. This means that all subsequent MIDI events sent on the same channel as the Channel Lock controller (the "logical" channel) will instead be transmitted on the newly locked (or "physical") channel.

This concept is perhaps best illustrated with a typical application of channel locking. Below is a list of events comprising a short XMIDI sequence to create a "machine gun" sound effect. (Timing and note velocity information has been omitted for simplicity).

Ch 02 Controller 114 = 1    ;XMIDI Patch Bank Select = 1
Ch 02 Patch = 5             ;MIDI Program Change to patch 5 ("gunshot")
Ch 02 Pitch Wheel 0         ;Pitch bend centered (no bend)
Ch 02 Controller 1 = 0      ;Modulation = 0
Ch 02 Controller 7 = 127    ;Volume = 127
Ch 02 Controller 10 = 64    ;Panpot = 64 (center of stereo field)
Ch 02 Controller 116 = 5    ;FOR loop = 1 to 5...
Ch 02 Note C 5 on           ;...sound a brief "gunshot" note...
Ch 02 Note C 5 off
Ch 02 Controller 116 = 127  ;...NEXT loop

This "machine gun" sequence would be ideal for use as part of an arcade game's sound-effects arsenal, except for one serious drawback: what happens if MIDI channel 2 is already being used by a background music sequence, or perhaps another sound effect? The controller values and patch change in the sequence above would certainly have an unfavorable effect on a romantic violin solo playing on channel 2. The problem could be solved by setting aside a block of active MIDI channels for use with overlaid sound-effects sequences, but this might be an unacceptable compromise for applications requiring playback of any but the simplest XMIDI sequences.

Channel locking and remapping is a much more satisfactory solution. When composing sequences for the XMIDI standard, the composer could assign all tracks in sound effects and other overlaid sequences to any desired MIDI channel. If an XMIDI Channel Lock controller is then inserted before the first Channel Voice event in the channel, the MSS driver can temporarily reassign a physical MIDI channel to the logical channel number, preventing the channel's use by any other sequence being played for as long as it is needed by the sequence which "locked" the channel. A not-so-obvious benefit of this scheme is that all sound-effects sequences can safely share the same logical channel numbers, since only the physical channel numbers recognized by the synthesizer are vulnerable to usage conflicts.

With channel locking installed, the machine gun sound-effect sequence might look like this:

Ch 02 Controller 110 = 127  ;XMIDI Channel Lock (seize channel)
Ch 02 Controller 114 = 1    ;XMIDI Patch Bank Select = 1
Ch 02 Patch = 5             ;MIDI Program Change to patch 5 ("gunshot")
Ch 02 Pitch Wheel 0         ;Pitch bend centered (no bend)
Ch 02 Controller 1 = 0      ;Modulation = 0
Ch 02 Controller 7 = 127    ;Volume = 127
Ch 02 Controller 10 = 64    ;Panpot = 64 (center of stereo field)
Ch 02 Controller 116 = 5    ;FOR loop = 1 to 5...
Ch 02 Note C 5 on           ;...sound a brief "gunshot" note...
Ch 02 Note C 5 off
Ch 02 Controller 116 = 127  ;...NEXT loop
Ch 02 Controller 110 = 0    ;XMIDI Channel Lock (release channel)

The sequence's new final event, a Channel Lock controller with the value 0, is actually unnecessary since all channels locked by a sequence are released automatically as soon as the sequence ends or playback is stopped. However, in sequences with multiple tracks, it is a good idea to explicitly release each locked channel as soon as it is no longer needed by the sequence, instead of waiting for all tracks to expire. This allows the XMIDI driver to restore the channel to the sequence from which it was "stolen," minimizing the disruption to the background music.

When a locked channel is released, either through a Channel Lock controller with a value below 64 or through a C call to the analogous AIL_release_channel function, the timbre bank, patch number, pitch wheel, and MIDI controllers in the channel are updated to their correct values before being returned to the service of the original sequence. This relieves the application of the responsibility of keeping track of these values while a channel is locked. Conversely, when a channel is locked by a Channel Lock controller or its complementary AIL_lock_channel function, the MIDI Sustain (Hold1) controller (64) in the channel is forced to its "off" condition and all notes playing in the channel are silenced. No other controller values or MIDI messages are initialized! It is essential for a sequence (or an application) which has just received a locked channel to initialize all MIDI parameters, including MIDI controllers likely to contain undesirable values, the XMIDI Patch Bank Select controller and MIDI Program Change number, and the MIDI pitch wheel, to appropriate values. (Avoid the temptation to accomplish this with MIDI Channel Mode messages such as All Notes Off or Reset All Controllers. Channel Mode messages may be interpreted differently by various synthesizers, and the XMIDI API code which maintains sequence state tables and other data structures makes no attempt to interpret them at all).

Next Topic (XMIDI Channel Lock Protect (111))

Previous Topic (XMIDI Sequence Branch (109))

Group: Extended MIDI Technical Reference
Related Functions: AIL_lock_channel, AIL_release_channel


XMIDI Channel Lock Protect (111)

Discussion

< 64: Channel is eligible for temporary reassignment by AIL_lock_channel or Channel Lock controllers

>= 64: Channel may not be locked (seized for reassignment)

Occasionally it may be desirable to prevent any sequence or application process from interrupting traffic on a given MIDI channel. Depending on its value, the XMIDI Channel Lock Protect controller will either render the physical MIDI channel in which it appears immune to seizure, or allow it to be considered for seizure when a Channel Lock controller message or AIL_lock_channel call is issued.

Next Topic (XMIDI Voice Protect (112))

Previous Topic (XMIDI Channel Lock (110))

Group: Extended MIDI Technical Reference
Related Functions: AIL_lock_channel


XMIDI Voice Protect (112)

Discussion

< 64: Voices playing in channel assume normal priority (release voice protection)

>= 64: Voices playing in channel assume highest possible priority (assert voice protection)

Available on some synthesizers, voice protection is an XMIDI feature which allows a sequence to discourage the polyphonic voice assignment algorithm from "stealing" synthesizer voices from notes played in a given MIDI channel when no free voices are available. If the Voice Protect controller's value is less than 64, voices assigned to notes playing in the channel will be considered for reassignment to play incoming note events. This is the default condition for each channel. Otherwise, the "voice priority" of notes in the channel will constantly assume its maximum value, preventing the channel's notes from being robbed of their voices. Voice protection should be used conservatively and released as soon as possible, since the synthesizer emulation code works best when allowed to make its own decisions regarding voice allocation.

Next Topic (XMIDI Timbre Protect (113))

Previous Topic (XMIDI Channel Lock Protect (111))

Group: Extended MIDI Technical Reference


XMIDI Timbre Protect (113)

Discussion

< 64: Timbre currently assigned to this channel's patch may be "discarded" (if least-recently-used) to make room in local timbre cache or synthesizer memory

>= 64: Timbre may not be discarded from cache or synthesizer memory

For information on timbre protection, refer to the descriptions of the AIL_protect_timbre / AIL_unprotect_timbre functions.

Next Topic (XMIDI Patch Bank Select (114))

Previous Topic (XMIDI Voice Protect (112))

Group: Extended MIDI Technical Reference
Related Functions: AIL_protect_timbre, AIL_unprotect_timbre


XMIDI Patch Bank Select (114)

Discussion

This controller may be used to "extend" the scope of MIDI Program Change (or Cakewalk "Patch") messages. Normally, any of 128 synthesizer patches may be selected with a Program Change message; however, the Patch Bank Select controller instructs the MSS XMIDI driver to associate custom timbres in any of 127 banks with synthesizer patches which are subsequently selected in a channel.

By convention, patch bank 0 is reserved for General MIDI built-in patch/timbre combinations, and for the Ad Lib-style instruments intended to emulate those patches. Custom timbres should generally be placed in patch banks 1 through 126. Timbre bank 127 is reserved for "drum kit" timbres to be used when playing note events on MIDI channel 10.

When a MIDI Program Change (or "patch") event is encountered, the XMIDI synthesizer driver looks in its collection of timbres from the Global Timbre Library or proprietary instrument bank for a custom timbre whose "patch number" is the specified Program Change number and whose "bank" is equal to the current Patch Bank Select controller value. If the timbre is found, the synthesizer is automatically instructed to associate the timbre with the patch which was just selected by the Program Change event. Under normal circumstances, the search for the requested timbre should not fail, since the driver should have been informed in advance of the need for the timbre via the AIL_init_sequence function.

The default Patch Bank Select controller value is 0. Therefore, MSS applications which do not require custom timbres may disregard this controller altogether. Otherwise, care must be taken to explicitly specify the Timbre Bank Select controller value to be used in each channel of every sequence and sound effect used by the application, since the default value of 0 is asserted only upon driver initialization - not when a channel is locked or when a sequence stops.

DLS patches are invoked in the normal way, with MIDI Program Change messages; however, it is recommended that the General MIDI bank-select controllers (0 and 32) be used instead of XMIDI Patch Bank Select (114) for all future work. In the MSS software DLS synthesizer, XMIDI Patch Bank Select emulates the GM bank controllers correctly, but this emulation is not supported by hardware-based synthesizer platforms.

Next Topic (XMIDI Indirect Controller Prefix (115))

Previous Topic (XMIDI Timbre Protect (113))

Group: Extended MIDI Technical Reference
Related Functions: AIL_init_sequence


XMIDI Indirect Controller Prefix (115)

Discussion

This controller specifies that the next Control Change message encountered in this channel should obtain its value from the Indirect Controller Array's nth byte entry, where n is the indirect controller prefix's own value. For more information on the Indirect Controller Array, see the AIL_register_ICA_array function.

Next Topic (XMIDI For Loop Controller (116))

Previous Topic (XMIDI Patch Bank Select (114))

Group: Extended MIDI Technical Reference
Related Functions: AIL_register_ICA_array


XMIDI For Loop Controller (116)

Discussion

1-127: Define beginning of MIDI data block to be played a total of v times, where v is the For loop controller's value

0: Define beginning of MIDI data block to be played indefinitely

This controller allows the creation of a loop within an XMIDI sequence. Its use is almost self-explanatory, especially for those familiar with BASIC or C's "for...next" construct. A loop value of 1 causes the block of MIDI/XMIDI events between the For controller and its corresponding Next/Break controller to be executed precisely once - as if the controllers did not exist. Values from 2 to 127 cause the event block to be executed from 2 to 127 times. A value of 0, on the other hand, causes the event block to loop indefinitely, interruptible only at the application's request.

There are four rules to bear in mind when using For...Next/Break loops:

* At least one XMIDI 'quantization interval' must separate the For and Next/Break loop controllers. In practice, this means that more than 1/120 second (8.4 milliseconds) of real time must elapse between these two events during playback. Otherwise, the application will "hang" forever, since neither the For nor the Next/Break controller automatically terminates the current interval.

* The branching effect caused by a Next/Break controller does not result in the note queue being flushed, unlike the operation of the AIL_branch_index function. Only the sequence pointer is adjusted by the Next/Break controller. Refer to the AIL_branch_index function description and the MDI_ALLOW_LOOP_BRANCHING preference for additional notes about sequence branching in general.

* Multi-track MIDI Format 1 files are converted to MIDI Format 0 during the XMIDI compilation process. This implies that loops placed on a single track will actually cause events in all other tracks to be repeated as well. In situations where it is desired to loop tracks independently of each other, a possible solution is to split the tracks into multiple XMIDI sequences and have the application play each sequence simultaneously.

* For...Next/Break controller loops may be nested up to 4 levels deep.

Next Topic (XMIDI Next-Break Loop Controller (117))

Previous Topic (XMIDI Indirect Controller Prefix (115))

Group: Extended MIDI Technical Reference
Related Functions: AIL_branch_index
Related Basic Types: MILES_PREFERENCES


XMIDI Next-Break Loop Controller (117)

Discussion

< 64: (Break) Loop iteration stops, regardless of the current For loop count

>= 64: (Next) Decrement innermost For loop count and, if nonzero, branch immediately to the innermost For controller event

One application of the Indirect Controller Prefix controller (q.v.) would be to turn a Next controller into a Break controller by providing a dynamic controller value as specified above. This feature may be used to introduce elements of application program control into sound-effect sequences. Otherwise, the Next controller should have a value greater than or equal to 64, in order to function in the manner detailed in the preceding For Loop Controller description.

Next Topic (XMIDI Clear Beat-Bar Count (118))

Previous Topic (XMIDI For Loop Controller (116))

Group: Extended MIDI Technical Reference


XMIDI Clear Beat-Bar Count (118)

Discussion

Value unused, 0-127.

This controller resets the current beat and measure counters to 0:0. See the AIL_sequence_position function description for information on the beat and measure counters.

Next Topic (XMIDI Callback Trigger (119))

Previous Topic (XMIDI Next-Break Loop Controller (117))

Group: Extended MIDI Technical Reference
Related Functions: AIL_sequence_position


XMIDI Callback Trigger (119)

Discussion

Value = trigger_value parameter passed to callback function, 0-127.

See the AIL_register_trigger_callback function description for information on callback functions.

Next Topic (XMIDI Sequence Branch Index (120))

Previous Topic (XMIDI Clear Beat-Bar Count (118))

Group: Extended MIDI Technical Reference
Related Functions: AIL_register_trigger_callback


XMIDI Sequence Branch Index (120)

Discussion

Value = marker_number parameter passed to AIL_branch_index function, 0-127.

See the AIL_branch_index function description for information on sequence branching.

Next Topic (Extended MIDI IFF (.XMI) Structure)

Previous Topic (XMIDI Callback Trigger (119))

Group: Extended MIDI Technical Reference
Related Functions: AIL_branch_index


Extended MIDI IFF (.XMI) Structure

Discussion

XMIDI sequence files are "preprocessed" MIDI sequence files. Created by the Miles Sound Studio utility described in the Tools Reference Section (or the AIL_MIDI_to_XMI function), XMIDI files are stored in accordance with Electronic Arts' Interchange File Format (EA IFF 85) standard. Below is a summary of the XMIDI format's technical details, which is presented as an aid to application developers with specialized needs not supported directly by the Miles Sound System.

The XMIDI file format preserves all of the information needed to faithfully reproduce the MIDI sequence's original sound, while discarding elements of the MIDI storage format that are redundant, inefficient, or otherwise unnecessary for real-time playback. An XMIDI file containing a single translated MIDI sequence often requires from 10% to 30% less storage space, and can be performed with substantially less background processing time.

Each XMIDI file contains a single IFF "CAT" chunk of type XMID. The CAT chunk contains at least one XMIDI sequence, whose local chunks are stored within a "FORM" chunk of type XMID. The XMIDI file may contain a chunk of type FORM XDIR which contains information about the file's collection of XMIDI sequences. The XDIR chunk is for the application's benefit, and is not currently required by the XMIDI drivers.

In the expression below, signifies a 32-bit "big endian" (or Motorola 680XX-style, MSB first) chunk length, which includes neither itself nor its preceding 4-character CAT, FORM, or local chunk name. Square brackets enclose optional chunks; ellipses are placed after the closing braces of chunks or data items which may be repeated.

[
  FORM < len > XDIR
  {
    INFO < len >
    U16 # of FORMs XMID in file, 1-65535
  }
]
CAT < len > XMID
{
  FORM < len > XMID
  {
    [
      TIMB < len >
      U16 # of timbre list entries, 0-16384
      {
        U8 patch number 0-127
        U8 timbre bank 0-127
      }
      ...
    ]
    [
      RBRN < len >
      U16 # of branch point offsets, 0-127
      {
        U16 Sequence Branch Index controller value 0-127
        U32 controller offset from start of EVNT chunk
      }
      ...
    ]
    EVNT < len >
    {
      U8 interval count (if < 128)
      U8  (if > 127)
    }
    ...
  }
  ...
}

TIMB and RBRN are optional chunks. RBRN is included only if XMIDI Sequence Branch Index (120) controllers appear in the original MIDI sequence. The mandatory EVNT chunk contains the quantized sequence events. EVNT must appear as the last local chunk in FORM XMID, while the other local chunks may appear in any order. consists of any MIDI Channel Voice, System Exclusive, or Meta-event except Note Off. The MIDI 'running status' convention is not used. Note On events are followed by their duration in intervals, expressed as a MIDI variable-length quantity (i.e., a string of 7-bit bytes stored most significant byte first, with the high bit set in all bytes except the last).

Next Topic (Extended MIDI Global Timbre Library File Format)

Previous Topic (XMIDI Sequence Branch Index (120))

Group: Extended MIDI Technical Reference
Related Sections: Miles Sound Studio
Related Functions: AIL_MIDI_to_XMI, AIL_init_sequence


Extended MIDI Global Timbre Library File Format

Discussion

For information about Global Timbre Library data in general, review the discussion of the GLIB program in the Tools-Reference Section, as well as the descriptions of timbre-related functions in the XMIDI Services Section.

In the expression below, ellipses are placed after the closing braces of data items which may be repeated.

File header, one entry for each timbre in file

{
  S8 timbre patch number
  S8 timbre bank number
  U32 offset of timbre length word from start of file
}
...

Structure of each timbre as stored in file

{
  U16 timbre length word (size of timbre in bytes + 2)
  {
    U8 timbre data byte
  }
  ...
}
...

Previous Topic (Extended MIDI IFF (.XMI) Structure)

Group: Extended MIDI Technical Reference


MSS Device Development Kit for DOS Sound Drivers

Discussion

The MSS DDK is used to create DOS sound drivers for new sound hardware. Sound card manufacturers use the DDK to create the .DIG and .MDI files that MSS uses to play sound under DOS. This chapter will describe the complete DDK interface specification, but the easiest way to write a sound driver is to start with one of the existing drivers and modify it. We supply many sample sound drivers to make this "development-by-modification" as simple as possible.

The DDK is found in a "mss6ddk.exe" installer. There is a subdirectory called "\dig" that contains the digital sound driver development kit, a subdirectory called "\mdi" that contains the XMIDI sound driver development kit, a subdirectory called "\oem" that contains notes and source code to some of the manufacturer-developed drivers, and, finally, a subdirectory called "\sndfont" that contains example code for programming the SoundFont capabilities of the SoundBlaster AWE32.

MSS sound drivers are essentially "tiny model" real-mode .COM files. Digital sound drivers have the .DIG extension and XMIDI drivers have the .MDI extension. They are loaded into memory by MSS at runtime, but not as TSR programs. MSS simply allocates a piece of real-mode memory and loads the image of the driver. MSS then hooks the real-mode image into the INT 66H interrupt chain. Once hooked in, MSS and the drivers communicate with a simple interrupt-based calling mechanism.

MSS Device Development Kit for DOS Sound Drivers
DOS Sound Driver Architecture
VDI_HDR describes a DOS sound driver's Driver Header Table.


DOS Sound Driver Architecture

Discussion

MSS-compatible digital sound drivers are essentially "tiny model" real-mode .COM files with the file suffix .DIG. MIDI interpreter drivers are similar in structure, and bear the standard suffix .MDI.

MSS drivers are loaded into memory by the application at runtime -- not as TSR programs. The area of memory occupied by a MSS driver must be paragraph-aligned (that is, the lower four bits of its offset address must be 0). MSS loads these sound drivers into the lower 1MB of physical memory, which is allocated under DPMI with a call to INT 31H Function 100H. MSS then communicates with these drivers through a standard interrupt-based calling mechanism.

The standard MSS communications interrupt is INT 66H. To call a sound driver function, the AX register must be set to the desired function number, the BX register must contain the desired driver number (see below), and an INT 66H call must be performed. Function numbers 400H - 4FFH are reserved for use by .DIG digital sound drivers, while functions 500H - 5FFH are assigned to .MDI music drivers. Functions 300H - 3FFH are initialization functions common to both driver types. Any functions not handled by a given MSS driver (including, for example, DIGPAK and MIDPAK driver calls, which share INT 66H with MSS) should be passed down to the previous INT 66H handler.

Up to 65,536 .DIG and .MDI drivers may be loaded simultaneously by the application, if desired, to provide true "surround-sound" effects with multiple sound cards. When making an MSS driver call, the BX register should contain the driver number specifying which driver in the INT 66H chain should handle the call. Driver numbers start at 0 and increase by 1 for each MSS driver loaded by the application.

Interrupts are disabled by default during execution of all driver calls, to guard against data coherency problems. Sound driver functions which require interrupts to be enabled, or which need large amounts of processing time, must explicitly enable interrupt service with an STI instruction. This should not be done without careful consideration of asynchronous data and hardware-state coherency issues. The CPU interrupt state is automatically restored upon exiting from a sound driver function.

Although the MSS API layer requires an 80386-class CPU, sound drivers should be developed for compatibility with all Intel processors including the 8086 and 80286, when possible. This will help prevent problems with specialized or embedded applications which may be developed with MSS.

In summary, MSS driver calls use the following form. All registers not used to return data from a given function are preserved, with the exception of AX.

AX: Input: 300H-3FFH (All drivers), 400H-4FFH (.DIG driver functions), 500H-5FFH (.MDI driver functions). Output: Status or returned value (1 is success, 0 is failure, -1 is not supported).

BX: Input: Driver number.

To provide a general "skeleton" template for MSS driver development, the MASM/TASM-compatible modules MSS_DIG.INC and MSS_MDI.INC are supplied as part of the MSS DDK.

Every MSS driver's binary image, regardless of driver type, begins with a structure of type VDI_HDR. This structure provides information which MSS needs in order to link the driver into the INT 66H chain and perform any necessary initialization tasks. The VDI_HDR structure also contains the driver number value which enables the driver to respond to calls made to it, while passing others down the INT 66H chain.

As defined in MSS.H, the Driver Header Table for .MDI and .DIG drivers uses the VDI_HDR structure.

Group: MSS Device Development Kit for DOS Sound Drivers
Related Structures: VDI_HDR


VDI_HDR

The structure VDI_HDR describes a DOS sound driver's Driver Header Table.

struct VDI_HDR
{
  U8 ID[8];
  U32 driver_version;
  IO_PARMS * common_IO_configurations;
  U16 num_IO_configurations;
  char * environment_string;
  IO_PARMS IO;
  U16 service_rate;
  U16 busy;
  U16 driver_number;
  U16 this_ISR;
  void * prev_ISR;
  U8 scratch[128];
  char dev_name[80];
};

In Members

ID[8]
is an eight-character string which identifies the MSS driver's type. In assembly language, for example, the ID string would be initialized with a statement of the form db 'AIL3xxx',26, where xxx is replaced by 'DIG' for .DIG digital sound drivers, and 'MDI' for .MDI XMIDI drivers.
driver_version
should be initialized to a hexadecimal value corresponding to the revision level of the DDK For instance, version 0.10 of the DDK would correspond to a driver_version value of 0000010H, while version 1.00 would be 00000100H. See the MSS_DIG.H file for the current DDK version number.
common_IO_configurations
points to an array of num_IO_configurations structures of type IO_PARMS (above). This is a list of commonly encountered user I/O port settings for the supported sound device(s). It offers a reasonably "safe" compromise for auto-detection of sound hardware -- one that lies between attempting detection at only one factory default setting and recklessly scanning dozens of I/O port combinations, as many other drivers have attempted to do in the past. num_IO_configurations may be initialized to 0 if appropriate.
num_IO_configurations
specifies how many I/O configurations are pointed to by the common_IO_configuration field.
environment_string
if not NULL, points to an ASCII environment variable name (such as 'BLASTER' for Creative Labs Sound Blaster drivers) which may be found on end-users' systems and used to identify the correct I/O parameters for the supported audio device. The programmer may be able to avoid the "risks" inherent in the auto-detection process by performing a getenv for this standard environment variable and, if the result is not NULL, calling Function 303H (Parse Environment String) to fill the VDI_HDR's IO_PARMS structure with the information derived from the variable.
IO
tells the driver what I/O parameters to use to communicate with the supported device. It must be initialized by either MSS or by calling Function 303H (Parse Environment String) prior to any calls to functions 304H - 402H.
service_rate
if greater than zero, the driver requires real-mode callback service at service_rate calls per second from MSS via Function 302H (Periodic Interrupt Service). Function 302H is typically employed only for .MDI drivers or .DIG drivers which support non-DMA-equipped audio adapters, such as PCMCIA or parallel-port devices. Most .DIG drivers will not need to use Function 302H for timing, as digital audio devices generally provide their own timing and interrupt capabilities.
busy
initialized to 0 by MSS before any driver functions are called. Its value will become non-zero during any INT 66H function call to the driver, or while any external interrupt service for audio devices is taking place. MSS will not attempt any type of interaction with a driver whose busy flag is nonzero.
driver_number
initialized by MSS to a unique driver number value. When an INT 66H call is received, the driver compares the caller's BX value with driver_number, responding to the call only if the two values are equal. Otherwise, the call is dispatched to the prev_ISR handler (below).
this_ISR
initialized by the driver at assembly time. Its value is the offset of the driver's INT 66H function dispatcher from the beginning of the driver image.
prev_ISR
initialized by MSS to the address of the INT 66H handler which was active prior to installation of this_ISR into the INT 66H chain. When an INT 66H call is received, the driver compares the caller's BX value with driver_number, responding to the call only if the two values are equal. Otherwise, the call is dispatched to the prev_ISR handler.
scratch[128]
provides a 128-byte array which may be used either as temporary workspace by any sound driver function or as a convenient real-mode memory buffer for communications between MSS and functions such as 303H (Parse Environment String).
dev_name[80]
is an 80-byte array which contains the ASCII name(s) of the driver's supported device(s). Characters past the end of the ASCII string should be initialized to 0.

Discussion

The driver header's ID, driver_version, and this_ISR fields are statically initialized at assembly time. common_IO_configurations, num_IO_configurations, environment_string, and service_rate must be initialized by Function 300H (Initialize Driver), and cannot be accessed by MSS until after this function is called. All other members, including busy, driver_number, and prev_ISR are initialized by MSS immediately upon loading and installing the driver, before any INT 66H calls to the driver can be made.

Group: MSS Device Development Kit for DOS Sound Drivers
Related Sections: DDK Digital Function: IRQ_acknowledge, DDK Digital Function: IRQ_validate, DDK Function: 302H Periodic Interrupt Service, DDK Function: 303H Parse Environment String, DDK Function: 304H Verify Device I/O Parameters, DDK Function: 305H Initialize Device, DOS Sound Driver Architecture
Related Basic Types: U16, U32, U8, char, char *, void *
Related Structures: IO_PARMS, VDI_HDR


DOS Sound Driver Generic Initialization Interface

Discussion

These functions must be supplied by both .DIG and .MDI drivers. See the "\dig" or "\mdi" directories for sample source code.

DOS Sound Driver Generic Initialization Interface
DDK Function: 300H Initialize Driver
DDK Function: 301H Get Driver Information
DDK Function: 302H Periodic Interrupt Service
DDK Function: 303H Parse Environment String
DDK Function: 304H Verify Device I/O Parameters
DDK Function: 305H Initialize Device
DDK Function: 306H Shut Down Device


DDK Function: 300H Initialize Driver

Discussion

Input:

AX = 300H
BX = Driver number

Output:

None

This function is called by MSS immediately upon loading and installing the driver. Its purpose is to initialize any internal data variables needed by the driver and to provide a means of "resetting" the driver without reloading it.

Group: DOS Sound Driver Generic Initialization Interface


DDK Function: 301H Get Driver Information

Discussion

Input:

AX = 301H
BX = Driver number

Output:

DX:AX = segment:offset pointer to DDT (Driver Description Table)
CX:BX = segment:offset pointer to DST (Driver State Table)

This function allows MSS to access various internal data structures in the driver. The two principal data structures are the DDT (Driver Description Table) and the DST (Driver State Table). Function 300H (Initialize Driver) should be called prior to calling this function.

Group: DOS Sound Driver Generic Initialization Interface


DDK Function: 302H Periodic Interrupt Service

Discussion

Input:

AX = 302H
BX = Driver number

Output:

None

If the VDI_HDR service_rate_required variable is non-zero, the driver requires real-mode callback service via this function at service_rate_required calls per second. Real-mode callback service is normally needed only for certain music-synthesis devices or non-DMA-equipped audio adapters such as PCMCIA or parallel-port devices.

Most .DIG drivers will not need to use this function for timing, as digital audio devices generally provide their own timing and interrupt capabilities.

Group: DOS Sound Driver Generic Initialization Interface
Related Structures: VDI_HDR


DDK Function: 303H Parse Environment String

Discussion

Input:

AX = 303H
BX = Driver number
DOS environment string copied by application to scratch area

Output:

AX = 1: String parsed successfully, IO member validated in VDI_HDR
AX = 0: String could not be parsed successfully, IO invalid

This function may be used to give the driver access to an operating system environment variable, to aid in identifying the correct I/O parameters to be used with the supported device.

As an example, systems with Creative Labs Sound Blaster-family devices installed normally have an MS-DOS environment variable called "BLASTER" which details, among other things, the I/O address, IRQ level, and DMA channel settings of the board. Consequently, all Sound Blaster-compatible sound drivers contain an embedded ASCII string 'BLASTER' at the address indicated by the DDT's *environment_string member. Before resorting to auto-detection, the application should perform a getenv call with this string and, if the result is not NULL, copy the resulting string to the VDI_HDR structure's scratch workspace and call this function. Assuming the function returns successfully, the VDI_HDR IO structure will contain the information from the parsed environment string.

Group: DOS Sound Driver Generic Initialization Interface
Related Structures: VDI_HDR


DDK Function: 304H Verify Device I/O Parameters

Discussion

Input:

AX = 304H
BX = Driver number
VDI_HDR IO structure contains I/O parameters to verify

Output:

AX > 0: Device I/O parameters verified successfully
AX = 0: Device with specified I/O parameters could not be found

This function should be called prior to Function 305H (Initialize Device) to verify that the VDI_HDR IO structure contains the correct I/O parameters for the device. Its normal use is to verify known I/O settings at application startup time, prior to initializing the sound driver. When used to auto-detect a supported device with unknown I/O parameters, only the IO_PARMS settings found in the DDT's *common_IO_configurations should be passed to the function. Arbitrary or excessive "scanning" with this function is likely to cause system crashes or other undesired effects. Installation programs which auto-detect sound cards should prompt the end user for permission to do so!

This function should not be called after Function 305H (Initialize Device), unless the driver is shut down first with a call to Function 306H (Shut Down Device).

The value returned in AX will equal 0 if the device did not respond. An AX value of 1 or greater indicates successful detection of the device; some implementations of this function may elect to return a hardware revision level in AX for diagnostic purposes.

Many devices use resident drivers or non-volatile hardware registers to maintain some or all of their I/O parameter settings. Function 304H handlers for these devices may access these settings through the appropriate device-specific mechanisms, and update the VDI_HDR IO_PARMS structure prior to returning successfully.

For digital drivers, the DDT's format_supported and format_data array members may be altered by this function in response to information obtained about the hardware during initialization. For example, a Sound Blaster-compatible device driver may increase format_data's minimum and nominal buffer size fields to reduce clicking with device versions that do not support auto-initialize DMA.

Digital devices which support both 8-bit and 16-bit samples often make use of a separate DMA channel for 16-bit processing. It is generally not necessary to validate both the 8- and 16-bit DMA channels when only one of the sample modes is required by the application. The DIG_DETECT options (below) allow MSS to avoid unnecessary detection failures by selecting which DMA channel options to verify.

#define DIG_DETECT_8_BIT_ONLY 0x0001
#define DIG_DETECT_16_BIT_ONLY 0x0002
#define DIG_DETECT_8_AND_16_BITS 0x0003

Group: DOS Sound Driver Generic Initialization Interface
Related Structures: IO_PARMS, VDI_HDR


DDK Function: 305H Initialize Device

Discussion

Input:

AX = 305H
BX = Driver number
VDI_HDR IO structure contains I/O parameters to use while driver active

Output:

AX = 1: Device successfully initialized
AX = 0: Hardware fault

This function should be called prior to functions 306H through 505H. Its purpose is to perform any hardware initialization tasks not addressed during the I/O validation process of Function 304H.

Function 304H (Verify Device I/O Parameters) must be called prior to this function.

This function may, at the developer's option, initialize panpot controls to their center level and set hardware-based reverberation and other effects to a neutral value. Initialization of these parameters is not necessary in cases where a user-accessible "control panel" is provided with the device.

This function may safely perform DOS or other system-level accesses, if necessary.

Group: DOS Sound Driver Generic Initialization Interface
Related Structures: VDI_HDR


DDK Function: 306H Shut Down Device

Discussion

Input:

AX = 306H
BX = Driver number

Output:

None

This function "turns off" the supported device, restores any hooked interrupt vectors, and shuts down the VDI driver. Failure to call this function prior to application shutdown may result in problems when attempting to run subsequent applications. After a call to this function, no further VDI calls should be made other than those which re-initialize the driver and device.

For XMIDI drivers, any active MIDI notes should be turned off by this function.

This function should not be called unless the device has been previously initialized with a call to Function 305H (Initialize Device).

This function may safely perform DOS or other system-level accesses, if necessary.

Group: DOS Sound Driver Generic Initialization Interface


DOS Digital Sound Driver Interface

Discussion

The digital sound driver interface defines all of the functions necessary for digital playback. Digital sound functions use function numbers 400H to 4FFH. See the sample drivers in "\dig" for example source code.

DOS Digital Sound Driver Interface
DDK Function: 400H Get/Set Digital Hardware Volume
DDK Function: 401H Start Digital Playback Command
DDK Function: 402H Stop Digital Playback Request
DDK Function: 403H Start Digital Recording Command
DDK Function: 404H Stop Digital Recording Request
DDK Function: 405H Vendor-Specific Extensions


DDK Function: 400H Get/Set Digital Hardware Volume

Discussion

Input:

AX = 400H
BX = Driver number
DX = 0-127: Set digitized sound volume level 0-127
DX = -1: Read and return current digitized sound volume

Output:

If setting hardware volume

AX = 0-127: Digitized sound volume 0-127 successfully set
AX = -1: Hardware volume control not available

If reading hardware volume

AX = 0-127: Current digitized sound volume level 0-127
AX = -1: Hardware volume control not available

The purpose of this function is to allow applications to calibrate the volume balance between MIDI music and digital sound effects. Its use is optional; no other driver function should alter hardware volume settings (except functions 305H and 306H, if desired).

IMPORTANT: To eliminate the possibility of speaker and/or hearing damage, under no circumstances should any driver alter the device's master volume setting! Master volume settings should be considered the domain of "control panel" utilities -- not individual third-party applications. If a device supports master volume control without a separate facility for digital audio volume, this function should return with AX = -1.

As a courtesy to users, it is recommended that the initialization and shutdown functions (305H and 306H, respectively) save and restore the hardware volume setting.

Group: DOS Digital Sound Driver Interface


DDK Function: 401H Start Digital Playback Command

Discussion

Input:

AX = 401H
BX = Driver number
CX = Sample rate in hertz (samples per second, not bytes per second)
DX = Mode index (see DDT for details)

Output:

None

This function initiates digital sound playback.

The following conditions must be met before calling this DDK Function:

* The driver has been initialized.

* The device I/O settings have been verified.

* The device has been initialized.

* The DST *DMA_buffer_A and *DMA_buffer_B variables have been set by MSS.

* The DMA buffer contents have been properly initialized by MSS.

* Real-mode callback service (if required) has begun.

* CX equals one of the three possible sample rates for the desired mode as specified by DX.

Subsequent calls to this function without an intervening call to Function 402H (Stop Digital Playback Request) will have no effect.

Group: DOS Digital Sound Driver Interface


DDK Function: 402H Stop Digital Playback Request

Discussion

Input:

AX = 402H
BX = Driver number

Output:

None

This function requests that digital playback be halted at the end of the current buffer. Since some devices do not function reliably when digitized sample playback is interrupted in progress, the application should not restart playback with a different sample rate or mode until the DST active_buffer variable becomes -1. The application may, however, cancel a pending Stop Digital Playback Request by calling Function 401H (Start Digital Playback Command) with the same mode and sample rate as previously used.

Group: DOS Digital Sound Driver Interface


DDK Function: 403H Start Digital Recording Command

Discussion

Input:

AX = 403H
BX = Driver number
CX = Sample rate in hertz (samples per second, not bytes per second)
DX = Mode index (see DDT for details)

Output:

AX = -1 if recording not supported

This function initiates digital sound recording, if supported. Its operation is otherwise identical to Function 401H (Start Digital Playback Command).

Since the MSS API doesn't support recording, few MSS drivers support this function.

Group: DOS Digital Sound Driver Interface


DDK Function: 404H Stop Digital Recording Request

Discussion

Input:

AX = 404H
BX = Driver number

Output:

None

This function stops digital sound recording at the end of the current buffer. Its operation is otherwise identical to Function 402H (Stop Digital Playback Request).

Group: DOS Digital Sound Driver Interface


DDK Function: 405H Vendor-Specific Extensions

Discussion

Input:

AX = 405H
BX = Driver number
CX = VSE feature identifier (see below)
DX:SI = Pointer to feature-specific input parameter block

Output:

AX = -1 if VSE feature not supported
DX:SI = Pointer to feature-specific output parameter block

By means of this function, MSS applications may take advantage of certain hardware-specific features not otherwise supported by the MSS DDK driver specifications. The Vendor-Specific Extensions (VSE) function provides an open-ended protocol for implementing such hardware-specific functions as interdriver communication, artificial surround sound or 3D sound, special effects, and tone or filter control.

To avoid conflicts and to ensure that MSS users can easily obtain access to new features, RAD will serve as a clearinghouse for vendor-specific extension identifier codes. Any vendor who implements support for a device-dependent feature should submit the following information to RAD:

1) Input parameter block structure

2) Output parameter block structure

3) Detailed description of feature, including input and output parameters and possible side effects 4) Technical support contact name and telephone number for use by application programmers

Upon receipt of the above information, RAD will assign a VSE feature identifier number which may be used to call the VSE feature from MSS.

Currently Reserved VSE Codes:

CX: 0 = Advanced Gravis Buffer-fill callback service (DX=buffer)
CX: 1 = QSound Labs spacial control features

Group: DOS Digital Sound Driver Interface


DOS XMIDI Sound Driver Interface

Discussion

The XMIDI sound driver interface defines all of the functions necessary for MIDI playback. XMIDI functions use function numbers 500H to 5FFH. See the sample drivers in "\mdi" for example source code.

DOS XMIDI Sound Driver Interface
DDK Function: 500H Get/Set MIDI Hardware Volume
DDK Function: 501H Initialize Instrument Manager
DDK Function: 502H Transmit MIDI Data
DDK Function: 503H Install Timbre Set
DDK Function: 504H Get Timbre Status
DDK Function: 505H Protect/Unprotect Timbre
DDK Function: 506H Vendor-Specific Extensions


DDK Function: 500H Get/Set MIDI Hardware Volume

Discussion

Input:

AX = 500H
BX = Driver number
DX = 0-127: Set MIDI sound volume level 0-127
DX = -1: Read and return current MIDI sound volume

Output:

If setting hardware volume

AX = 0-127: MIDI sound volume 0-127 successfully set
AX = -1: Hardware volume control not available

If reading hardware volume

AX = 0-127: Current MIDI sound volume level 0-127
AX = -1: Hardware volume control not available

The purpose of this function is to allow applications to calibrate the volume balance between MIDI music and digital sound effects. Its use is optional; no other driver function should alter hardware volume settings (except functions 305H and 306H, if desired).

IMPORTANT: To eliminate the possibility of speaker and/or hearing damage, under no circumstances should any driver alter the device's master volume setting! Master volume settings should be considered the domain of "control panel" utilities -- not individual third-party applications. If a device supports master volume control without a separate facility for digital audio volume, this function should return with AX = -1.

As a courtesy to users, it is recommended that the driver initialization and shutdown functions (305H and 306H, respectively) save and restore the hardware volume setting.

Group: DOS XMIDI Sound Driver Interface


DDK Function: 501H Initialize Instrument Manager

Discussion

Input:

AX = 501H
BX = Driver number
DST library_directory and GTL_filename strings valid, if applicable

Output:

AX = 1: Instrument management successfully initialized
AX = 0: Bad or missing instrument file, insufficient synthesizer RAM, or other error

This function is called by MSS after Function 305H (Initialize Device) and before any MIDI data is played. Its purpose is to allow the driver to initialize its instrument data management routines and open any instrument files needed during playback.

This function may safely perform DOS or other system-level accesses, if necessary.

See the descriptions of the DDT's library_environment and GTL_suffix members for more information.

Group: DOS XMIDI Sound Driver Interface


DDK Function: 502H Transmit MIDI Data

Discussion

Input:

AX = 502H
BX = Driver number
CX = # of MIDI messages in DST MIDI_data[] area
MIDI message set copied by API to DST MIDI_data[] area

Output:

None

This function is the primary message-passing mechanism between MSS and the driver layer. Its input data consists of from 1 to n standard MIDI messages (of either Channel Voice or System Exclusive type), where n is limited by the size of the Driver State Table's 512-byte MIDI_data[] area. The actual number of MIDI messages to be processed is passed to the function in the CX register. Upon calling this function, the list of MIDI messages supplied by MSS will be transmitted or interpreted by the driver, in order of appearance. The driver processes each MIDI message with no delta-time intervals or intermessage delays. This "message list" concept is intended to reduce the large number of protected-mode to real-mode transitions that would be incurred if the function were designed to handle only one MIDI message per call.

The function handler does not need to handle MIDI running status, as MSS is responsible for associating the proper status byte with each message prior to insertion into the MIDI_data[] buffer.

This function should not perform DOS or other system-level accesses unless absolutely necessary.

Note: System Exclusive messages begin with the status byte $F0 or $F7, and are passed to the driver using the format given in the Standard MIDI Files 1.0 specification. This allows MSS to simply copy an entire System Exclusive event from the XMIDI file (or the buffer passed to the AIL_send_sysex_message function) to the driver's MIDI_data[] area. $F7 messages do not normally appear in PC MIDI traffic, so their implementation is optional.

For convenience, the Standard MIDI Files 1.0 System Exclusive format is reprinted in the description of the AIL_send_sysex_message function.

Group: DOS XMIDI Sound Driver Interface
Related Functions: AIL_send_sysex_message


DDK Function: 503H Install Timbre Set

Discussion

Input:

AX = 503H
BX = Driver number
XMIDI TIMB chunk image copied to DST MIDI_data[] area

Output:

AX = 1: All timbres successfully installed (or already present)
AX = 0: Error (BX = bank/patch specifier for failed operation)

The term "timbre" (pronounced TIM-ber or TAM-ber), as used in all MSS documentation, refers to the set of data which determines all performance characteristics of a musical instrument. The data describing a timbre may occupy as little as 14 bytes for a Yamaha OPL2-type FM voice, or several hundred kilobytes for an ultra-high-quality wavetable instrument definition. Additionally, some synthesizers may require that multiple levels of "patches," "waveforms," "multisamples," "presets," or other constructs be considered as aspects of the timbre definition as it relates to MSS-based MIDI performance.

Under the MSS 2.X standard, the API module allowed extensive application-level control over the management of instrument data. Instrument data for all supported synthesizers, regardless of voice format, was maintained in a GTL file, or Global Timbre Library file. The GTL file concept was ideal for working with highly-programmable synthesizers with relatively small timbre data sizes, such as the OPL2, OPL3, and Roland MT-32 platforms. However, MSS 2.X's technique of allowing the application program to manage timbres directly proved inflexible with the arrival of General MIDI and its accompanying entourage of wavetable synthesizers. Often, instrument definitions for the new synthesizers could no longer be shoehorned into monolithic, easily managed blocks of application memory. Discouraged by a multitude of incompatible, proprietary "standards," third-party tools for the creation and archival of wavetable samples were rare to nonexistent. OEM driver developers were thwarted in their efforts to resolve these issues by MSS 2.X's strict prohibition against DOS or other system calls within drivers.

The GTL standard remains in place under the current MSS, but several fundamental changes have occurred in the area of timbre management. The most important of these changes is that the driver, not the application, is now responsible for accessing GTL files, proprietary instrument library files, or both. Virtually all MSS 2.X applications contained a "timbre request" loop similar to the following:

while ((treq = AIL_timbre_request(driver,sequence)) != 0xffff)
{
   bank = treq / 256; patch = treq % 256;
   data = load_global_timbre(GTL,bank,patch);
   if (timb != NULL)
   {
      AIL_install_timbre(driver,bank,patch,data);
      free(timb);
   }
}

This loop would typically be executed after registering an XMIDI sequence with MSS, and before starting playback. The old AIL_timbre_request function would examine the XMIDI file image to check for timbres used by the sequence which did not correspond to instruments currently present in the timbre cache. If any timbres were "requested" in this manner, the application would open the GTL file and fetch the timbre's data block, supplying it to the driver with a call to AIL_install_timbre. This process would continue until all timbres required to play the XMIDI sequence had been uploaded to the synthesizer or cached in system RAM, depending on the synthesizer platform.

Current MSS drivers which support MSS 2.X-compatible Global Timbre Library files must implement the basic algorithm above in Function 503H (Install Timbre Set). Most OEM-developed drivers, however, will not need to deal with GTL compatibility. Instead, the Function 503H (Install Timbre Set) handlers in these drivers will either return immediately with AX = -1 if the synthesizer does not support uploadable instruments or if the complete instrument set is present in ROM, or, in cases where uploadable instruments are supported and/or required, handle the necessary uploading and memory management tasks in a manner transparent to MSS.

The list of timbres required to play a given XMIDI sequence appears in the sequence's XMIDI file image in the form of an IFF (Interchange File Format) chunk of type TIMB:

[
   TIMB
   U16 # of timbre list entries, 0-16384
   {
      U8 patch number 0-127
      U8 timbre bank 0-127
   }
   ...
]

Prior to calling this function, the entire TIMB chunk is copied to the DST's 512-byte MIDI_data[] array. This is the same area of memory used to communicate with Function 502H (Transmit MIDI Data). TIMB chunks longer than 512 bytes will be split into smaller sub-chunks and passed in subsequent calls to the function. The patch number for each timbre entry corresponds to the normal MIDI Program Change controller value used to associate a patch with a given MIDI channel. Through the addition of the XMIDI Patch Bank Select controller (114) to the MSS MIDI implementations, the basic MIDI Program Change architecture has been extended to accommodate up to 16,384 unique instruments by combining a timbre bank (also called a patch bank) value with each patch number. Patch number/timbre bank pairs are often expressed as two-byte integers or bank/patch specifiers, in which the low byte corresponds to the patch number and the high byte corresponds to its timbre bank.

By default, the timbre bank value for channels which do not use the XMIDI Patch Bank Select controller is 0. Under MSS 2.X, patch bank 0 corresponded to the default MT-32 instrument set, or its emulated equivalent on the Ad Lib and other synthesizers. Under the current MSS, however, patch bank 0 now corresponds to the General MIDI patch set. Other bank numbers, chosen by the composer, must be used for custom instruments or MT-32 emulation. This change has been made in response to the overwhelming success of General MIDI in the interactive music field, and the accompanying decline in importance of the older MT-32 MIDI standard among MSS users.

This function may safely perform DOS or other system-level accesses where necessary. It will never be called from an unprotected asynchronous interrupt handler, or under conditions which preclude the availability of DOS and BIOS services.

Group: DOS XMIDI Sound Driver Interface
Related Functions: AIL_install_timbre


DDK Function: 504H Get Timbre Status

Discussion

Input:

AX = 504H
BX = Driver number
CX = Bank (CH)/patch (CL) specifier to test

Output:

AX = 1: Timbre is present in synthesizer memory or local cache
AX = 0: Timbre is not present in synthesizer memory or local cache

This function returns with AX = 0 if the timbre with bank/patch specifier CX is not currently present in the synthesizer memory or internal timbre cache associated with the driver. This function is intended primarily for diagnostic and optimization purposes.

Group: DOS XMIDI Sound Driver Interface


DDK Function: 505H Protect/Unprotect Timbre

Discussion

Input:

AX = 505H
BX = Driver number
CX = Bank (CH)/patch (CL) specifier to protect/unprotect
DX = 1: Protect timbre
DX = 0: Unprotect timbre

Output:

AX = 1: Timbre was previously protected from deletion
AX = 0: Timbre was not previously protected from deletion

This function prevents timbre CX from being discarded from the synthesizer memory or local timbre cache ("protected"), or subjects the timbre to the action of the synthesizer's normal timbre replacement algorithm ("unprotected").

If the synthesizer memory or local timbre cache does not contain sufficient space for a timbre to be installed by Function 503H (Install Timbre Set), one or more timbres (typically the timbre(s) least recently used to play notes) may be discarded from memory to make room. This function provides a means of protecting a given timbre against deletion, and of removing such protection. Neither function will have any immediate effect on the contents of timbre memory.

Timbres installed with Function 503H (Install Timbre Set) are "unprotected" by default. Timbre protection may be useful in cases where it is desirable to play little-used sound-effect or music sequences at widely varying intervals during the course of an application, while avoiding any delays associated with loading and transmitting their custom timbres. Excessive use of timbre protection may cause infinite loops to occur at runtime, since the caching mechanism may be forced to discard timbres which were requested and loaded earlier in the current call to Function 503H (Install Timbre Set).

If both the bank and patch specifiers are equal to -1 (CX = 0FFFFH), the function will protect or unprotect all timbres in the cache.

The action of this function is analogous to the Extended MIDI Control Change event 113 (Timbre Protect). Not all synthesizers which perform timbre management must support this function, however.

This function returns 0 if the previous timbre protection state is unknown.

Group: DOS XMIDI Sound Driver Interface


DDK Function: 506H Vendor-Specific Extensions

Discussion

Input:

AX = 506H
BX = Driver number
CX = VSE feature identifier (see below)
DX:SI = Pointer to feature-specific input parameter block

Output:

AX = -1 if VSE feature not supported
DX:SI = Pointer to feature-specific output parameter block

By means of this function, MSS applications may take advantage of certain hardware-specific features not otherwise supported by the DDK driver specifications. The Vendor-Specific Extensions (VSE) function provides an open-ended protocol for implementing such hardware-specific functions as interdriver communication, artificial surround sound or 3D sound, special effects, and tone or filter control.

To avoid conflicts and to ensure that MSS users can easily obtain access to new features, RAD will serve as a clearinghouse for vendor-specific extension identifier codes. Any vendor who implements support for a device-dependent feature should submit the following information to RAD:

1) Input parameter block structure

2) Output parameter block structure

3) Detailed description of feature, including input and output parameters and possible side effects

4) Technical support contact name and telephone number for use by application programmers

Upon receipt of the above information, RAD will assign a VSE feature identifier number which may be used to call the VSE feature from MSS.

Currently Reserved VSE Codes

CX: 0 = Roland or other: write string in scratch[] array to front-panel display
CX: 1 = QSound Labs spacial control features

Group: DOS XMIDI Sound Driver Interface


DDK Support Routines for Digital Sound Drivers

Discussion

These functions are provided by MSS_DIG.INC, the standard assembly-language header file for MSS .DIG drivers. Chosen from among the functions needed by most digital sound drivers, these routines should be used whenever possible to accelerate driver development and debugging. This section is intended to serve as a quick-reference guide to the MSS_DIG.INC support functions; refer to their implementations in MSS_DIG.INC and their associated variables for more information. The example drivers included with the MSS DDK make extensive use of these functions.

DDK Support Routines for Digital Sound Drivers
DDK Digital Function: INT66H_dispatch
DDK Digital Function: DIG_init
DDK Digital Function: DMAC_disable
DDK Digital Function: DMAC_enable
DDK Digital Function: DMAC_program
DDK Digital Function: ASC_val
DDK Digital Function: RAD_wait
DDK Digital Function: IRQ_hook
DDK Digital Function: IRQ_unhook
DDK Digital Function: IRQ_validate
DDK Digital Function: IRQ_acknowledge


DDK Digital Function: INT66H_dispatch

Discussion

Input:

Function-dependent registers

Output:

Function-dependent registers
All registers preserved (except returned values)

Purpose:

INT 66H function dispatcher for .DIG driver

Notes:

Called from API level via INT 66H

Group: DDK Support Routines for Digital Sound Drivers


DDK Digital Function: DIG_init

Discussion

Input:

Nothing

Output:

Nothing
All registers changed

Purpose:

Initializes common driver variables; performs far pointer fixups based on driver CS: value

Notes:

Must be called prior to any other VDI functions

Group: DDK Support Routines for Digital Sound Drivers


DDK Digital Function: DMAC_disable

Discussion

Input:

DMA_channel

Output:

Nothing
All registers changed

Purpose:

Masks DMA channel, inhibiting DMA transfers

Group: DDK Support Routines for Digital Sound Drivers


DDK Digital Function: DMAC_enable

Discussion

Input:

DMA_channel

Output:

Nothing
All registers changed

Purpose:

Unmasks DMA channel, enabling DMA transfers

Group: DDK Support Routines for Digital Sound Drivers


DDK Digital Function: DMAC_program

Discussion

Input:

DMA_channel = DMA channel in use (0-7)
DMA_mode = Selected DMAMODE type for transfer
DMA_buffer = DMA buffer address in segment:offset format
DMA_cnt = DMA byte count-1 (0-65535 = 1-65536 bytes)

Output:

Nothing
All registers changed

Purpose:

Program DMA controller to perform transfer from lower 1MB based on previously selected mode and channel

Notes:

DMA transfer may be enabled by subsequent call to DMAC_enable

Group: DDK Support Routines for Digital Sound Drivers


DDK Digital Function: ASC_val

Discussion

Input:

AX = Number base (2-16)
BX = Offset of string in scratch[] array

Output:

AX = Value of number, or -1 if invalid input
BX = Offset of first character after end of string
All registers changed

Purpose:

Returns value of positive integer represented as ASCII string terminated with 0 or space

Notes:

Used by Function 303H (Parse Environment Variable)

Skips leading whitespace

Group: DDK Support Routines for Digital Sound Drivers


DDK Digital Function: RAD_wait

Discussion

Input:

AX = Number of intervals to delay

Output:

Nothing
All registers preserved

Purpose:

System- and CPU-independent delay: waits approximately 16 millisecond per interval

Group: DDK Support Routines for Digital Sound Drivers


DDK Digital Function: IRQ_hook

Discussion

Input:

AX = IRQ channel 0-15
DX = offset of ISR in driver code segment

Output:

DX:BX = previous ISR address
CX = previous contents of PIC mask registers
All registers changed

Purpose:

Enables IRQs on desired channel and installs ISR

Notes:

This function returns all data necessary to completely restore the status and ISR address of the selected IRQ channel. These values should be preserved and passed to IRQ_unhook prior to driver termination.

Group: DDK Support Routines for Digital Sound Drivers


DDK Digital Function: IRQ_unhook

Discussion

Input:

AX = IRQ channel 0-15
DX:BX = address of previous ISR as returned from IRQ_hook
CX = previous status of PIC mask registers

Output:

Nothing
All registers changed

Purpose:

Restores IRQ channel status

Notes:

The status bit and ISR for the given IRQ are restored based on the input variable values. No other PIC status bits are altered.

Group: DDK Support Routines for Digital Sound Drivers


DDK Digital Function: IRQ_validate

Discussion

Input:

IRQ variable in VDI_HDR = interrupt #

Output:

Carry set if IRQ valid
All registers preserved

Purpose:

Tests for spurious or invalid IRQ signals

Notes:

On many IBM AT-compatible systems, spurious IRQ 7 signals frequently occur. This function should be called at the beginning of the sound ISR to reject these false IRQs.

If IRQ_validate returns with the carry flag clear, the ISR should IRET immediately, without processing or acknowledging the interrupt.

Does not require valid DS register.

Group: DDK Support Routines for Digital Sound Drivers
Related Structures: VDI_HDR


DDK Digital Function: IRQ_acknowledge

Discussion

Input:

IRQ variable in VDI_HDR = interrupt #

Output:

Nothing
All registers preserved

Purpose:

Acknowledges the current IRQ

Notes:

This routine must be called prior to returning from a sound ISR. It sends an end-of-interrupt (EOI) command to the Programmable Interrupt Controller (PIC) device, to prepare for subsequent interrupts.

It is not necessary (or advisable) to call IRQ_acknowledge if the IRQ_validate function (above) returns with C=0.

Does not require valid DS register.

Group: DDK Support Routines for Digital Sound Drivers
Related Structures: VDI_HDR


DDK Support Routines for XMIDI Sound Drivers

Discussion

These functions are provided by MSS_MDI.INC, the standard assembly-language header file for MSS .MDI drivers. Chosen from among the functions needed by most MIDI sound drivers, these routines should be used whenever possible to accelerate driver development and debugging. This section is intended to serve as a quick-reference guide to the MSS_MDI.INC support functions; refer to their implementations in MSS_MDI.INC and their associated variables for more information. The example drivers included with MSS make extensive use of these functions.

DDK Support Routines for XMIDI Sound Drivers
DDK XMIDI Function: INT66H_dispatch
DDK XMIDI Function: MDI_init
DDK XMIDI Function: ASC_val
DDK XMIDI Function: RAD_wait


DDK XMIDI Function: INT66H_dispatch

Discussion

Input:

Function-dependent registers

Output:

Function-dependent registers
All registers preserved (except returned values)

Purpose:

INT 66H function dispatcher for .MDI driver

Notes:

Called from API level via INT 66H

Group: DDK Support Routines for XMIDI Sound Drivers


DDK XMIDI Function: MDI_init

Discussion

Input:

Nothing

Output:

Nothing
All registers changed

Purpose:

Initializes common driver variables; performs far pointer fixups based on driver CS: value

Notes:

Must be called prior to any other MSS functions

Group: DDK Support Routines for XMIDI Sound Drivers


DDK XMIDI Function: ASC_val

Discussion

Input:

AX = Number base (2-16)
BX = Offset of string in scratch[] array

Output:

AX = Value of number, or -1 if invalid input
BX = Offset of first character after end of string
All registers changed

Purpose:

Returns value of positive integer represented as ASCII string terminated with 0 or space

Notes:

Used by Function 303H (Parse Environment Variable).

Skips leading whitespace.

Group: DDK Support Routines for XMIDI Sound Drivers


DDK XMIDI Function: RAD_wait

Discussion

Input:

AX = Number of intervals to delay

Output:

Nothing
All registers preserved

Purpose:

System- and CPU-independent delay: waits approximately 16 millisecond per interval

Group: DDK Support Routines for XMIDI Sound Drivers


Change Log

Miles Sound System SDK 7.2a

Discussion

This change log includes the entire Miles Sound System development history.

Changes from version 7.1a to 7.2a (12-20-2007)

  • Multichannel Ogg Vorbis files are now fully supported by the MSS API. They may be played with either AIL_open_stream or AIL_set_named_sample_file.
  • Multichannel (WAVEFORMATEXTENSIBLE) PCM .WAV files are now supported via AIL_set_named_sample_file.
  • The Miles Sound Player now supports multichannel .WAV and Ogg Vorbis files.
  • Added new WavMux.exe command-line utility to create multichannel .WAV files which may be played directly as static HSAMPLES or converted to multichannel Ogg Vorbis files, e.g., with the free OggDrop encoder, for either static playback or streaming.
  • Extensive simplifications made to FAQ "How do I use multi-channel sound output in Miles?" Specifically, the new MSS_SPEAKER enum type eliminates all channel-count dependencies in level-control function calls.
  • Several API functions related to per-channel level control have been changed to accommodate multichannel source support using the new MSS_SPEAKER type, and are now more programmer-friendly as well. These functions include AIL_set_sample_channel_levels, AIL_sample_channel_levels, AIL_set_speaker_reverb_levels, AIL_speaker_reverb_levels, and AIL_calculate_3D_channel_levels.
  • Added AIL_sample_channel_count function to return the channel width (1=mono, 2=stereo, >2=multichannel) of the specified HSAMPLE.
  • Added AIL_sample_output_levels function to return the final amplitude scale factor applied by the MSS mixer to any given HSAMPLE. This takes all scaling sources into account, including 3D distance and cone functions (both default and user-supplied), AIL_set_sample_channel_levels, and the various volume/pan functions.
  • AIL_init_sample's return type has been changed from void to S32. See the function description for details.
  • The AILSOUNDINFO structure now includes a 32-bit channel_mask member which can be used to specify gaps in the default (WDM-based) channel order for multichannel samples.
  • Added AIL_set_sample_buffer_count and AIL_sample_buffer_count to allow the application to determine the number of buffers used for low-level streaming. Changed AIL_sample_buffer_ready to AIL_sample_buffer_available, and modified the parameters of AIL_sample_buffer_info. If your application uses these low-level streaming functions, you should carefully review the function descriptions and the dbtest.cpp example when upgrading to this version of MSS.
  • Fixed a bug that could cause lockups when calling AIL_close_digital_driver after unplugging headphones on certain Windows systems.
  • Added WIN32_POSITION_ERR property for AIL_platform_property function to allow the application to detect removal of headphones, speakers, or other sound hardware at runtime.
  • AIL_set_sample_51_volume_pan and AIL_set_sample_51_volume_levels now establish consistent front/back and left-right levels for all output modes, not just 5.1 modes.
  • Fixed a bug that could cause audible artifacts when using software DSP filters (including the built-in LPF) with EAX/DirectSound3D providers
  • Fixed a memory leak in the Xbox 360 implementation of AIL_close_digital_driver.
  • Cleaned up some IO error handling code on the Wii.
  • Fixed a bug in the Wii init code that was causing the digital latency to be too high.
  • Removed 500 ms of silence at the front of the "coolmidi" sample MIDI file.
  • Lowered the DLS synthesizer startup latency.
  • Fixed a (typically-harmless) bug in AIL_filter_DLS_with_XMI that could truncate the output file by 8 bytes.

Changes from version 7.0x to 7.1a (06-25-2007)

  • Released the final version of Miles for Nintendo Wii! We've done lots of PPC assembly optimizations to make Miles run super-fast on this great little CPU. We are really happy with the results - check it out!
  • Built the Xbox 360 version with the new June XDK. If you switch your game to the June XDK, then you must update to this version.
  • Fixed a bug on the pre-MacOS X version of Miles where streaming could skip.
  • Fixed bug that could cause a crash at shutdown time when using AIL_register_trace_callback.

Changes from version 7.0w to 7.0x (06-01-2007)

  • On Windows, fixed a bug in our SSE memset where machines with SSE but without SSE 2 would crash.
  • On MacOS, fixed a problem with SSE detection - MP3 playback will now be much faster.
  • On MacOS, fixed stack alignment problem on the x86 DLL loader.
  • Cleaned up a few of the build batch files.

Changes from version 7.0v to 7.0w (05-10-2007)

  • Changed the default falloff power for multichannel positioning from 1.0 to 3.0. You may wish to review the AIL_set_speaker_configuration function to understand how this change affects the behavior of the MSS 3D positioner.
  • The AIL_set_sample_channel_levels function can now be used to modify the channel levels established by the 3D positioner. In previous versions, this function had no effect on 3D-positioned HSAMPLEs and HSTREAMs.
  • It is now possible to apply 3D positioning to stereo files. 3D-positioned stereo sources will be downmixed to mono. Previous versions of MSS did not support 3D positioning of stereo sources.
  • Fixed a bug that could cause truncated playback of extremely-short XMA samples.
  • Fixed a bug that could cause XMA samples to fail to begin playing under certain conditions.
  • Fixed a bug that caused the auto_3D_wet_atten parameter for AIL_set_sample_3D_distances to be ignored for sounds beyond the maximum distance from the listener.
  • Fixed a bug on Mac that would cause a lockup, if you called AIL_shutdown twice.
  • Updated to the PS3 1.60 SDK.
  • Updated to the Xbox 360 April SDK.
  • Updated to the Visual Studio 2005 on Windows.
  • Updated to the Wii 2.4 patch 3 SDK.
  • Added internal SSE versions of memcpy, memmove and memset on Win32.

Changes from version 7.0u to 7.0v (02-1-2007)

  • Fixed a bug that could cause memory corruption during DSP filtering on PS3.
  • Fixed a bug that could cause output channel levels to change during stream-seek operations.
  • The capture filter now supports Xbox and Xbox 360 in addition to Windows.
  • Xbox 360 is always opened in MSS_MC_51_DISCRETE mode regardless of the channels parameter passed to AIL_open_digital_driver.

Changes from version 7.0t to 7.0u (01-10-2007)

  • Added AIL_CPU_AFFINITY preference for Xbox 360.
  • Renamed the MP3Loop.exe utility to MakeLoop.exe, and added support for ADPCM loop generation.
  • Added -r option to MakeLoop.exe.
  • Fixed a bug that could cause certain ASI codecs and filter providers to crash on CPUs without SSE support.
  • Added the AIL_platform_property function to allow applications to control Miles's thread affinity and other platform-specific behavior.

Changes from version 7.0s to 7.0t (11-16-2006)

  • Added the new MP3Loop.exe command line tool. This tool will create loopable MP3 files automatically!
  • Worked around a compiler code-gen bug on the Xbox 360 in the Ogg decoder.
  • Switched to using the pthread library on mach-O MacOS.
  • Simplified the memory allocator on mach-O MacOS.
  • Made the streaming API use a background thread on MacOS when not using async file IO (which usually means mach-O).
  • Removed the dynamic MIDI playback timing adjustment code on Mac (since Macs are so much faster now-a-days).
  • Changed the PS3 thread code to allow the system to be shutdown on a thread other than the one that started it.
  • Fixed a bug in the PS3 stereo ADPCM decoder.
  • Made the MIDI to XMI convert tolerate bad MIDI files that have partial events at the end of the file.
  • Made the 5.1 volume functions work on other platforms when running in 5.1 speaker mode.
  • AIL_inspect_MP3 now reads some of the LAME specific information in an MP3 file.
  • Fixed a bug when playing very short Ogg files where the first packet would repeat.

Changes from version 7.0r to 7.0s (10-04-2006)

  • Added custom_filter.cpp, a console application which demonstrates the basics of writing an MSS-compatible DSP pipeline filter.
  • Discontinued use of a compiler optimization (-Oz) which was causing crashes in Xbox 360 release-mode builds.
  • Added AIL_set_file_async_callbacks function docs for the PS2 and Mac versions, and clarified the documentation for file-callback support in general.
  • Fixed a bug in AIL_set_file_callbacks that prevented it from disabling asynchronous file operations on the PS2.
  • Updated the PS3 library and examples to the 096.002 SDK.
  • Updated to the Xbox 360 September XDK build.

Changes from version 7.0q to 7.0r (9-17-2006)

  • Added an Intel Mac version of Miles. This platform has all the features of the Windows version, including identical performance. The performance is identical because rather than port all of our assembly, we instead wrote a DLL loader and load the Windows RIB DLLs on MacOS!
  • Fixed a too-conservative locking situation in the streaming API that would cause one of the disc buffers to not preload with MP3 or Ogg data. So, even if you called AIL_service_stream to fill the internal buffers, when you began playback, you could stall while a disk seek happened.
  • Tweaked the streaming API to not lock the mixer mutex while IO is running, so that if you take a large IO hit on a background stream thread, then normal in-memory and other well-cached streams won't skip.
  • Fixed a silly bug on the PS3 where a thread handle was leaked for each stream that was played.
  • Fixed a crash bug in the AIL_quick_load_mem function.
  • Split the definitions of the driver properties and sample properties. This will require a few changes on the application side if you are using DSP filters or EAX preferences. Usually, you will simply have to change enums like DP_FILTER_0 to SP_FILTER_0.
  • Removed the C runtime from most of the RIB DLLs (so they can be used on MacOS) which had the side effect of shrinking most of the binary files by 20 to 60K.
  • Removed the Ogg encode routines from the function tables which shrunk the Ogg decoder's code footprint in half.
  • Moved the multi-channel copy and the adpcm decompressor over to a separate mixer module. On Intel Mac, this module is separate (mssmixer.mix), but on all other platforms, it remains built-in to the Miles library directly. This moved a fair amount of code around.
  • Build with better switches on MacOS PPC, so fewer internal functions are exported.

Changes from version 7.0p to 7.0q (8-21-2006)

  • Updated the PPC mixer assembly to not use any microcoded asm instructions.
  • Fixed a bug that could cause crashes when streaming .XMA files (Xbox360 only).
  • Fixed a bug that was causing crashes on the Xbox360 with the call-logging debug feature enabled.
  • Fixed a bug that could prevent listener-orientation changes from taking effect on non-Win32 platforms.
  • AIL_open_digital_driver now fails gracefully on generic "Surround sound speakers" Win32 configurations if MSS_MC_USE_SYSTEM_CONFIG is selected when matrix filter providers are not available.
  • NULL HPROVIDER pointers may now be passed to AIL_find_filter.
  • Added listener-orientation control to examms.exe example.
  • Fixed a bug in AIL_set_sample_low_pass_cut_off that could cause noise on samples played through drivers opened at lower sample rates.

Changes from version 7.0n to 7.0p (7-20-2006)

  • On the PS3, moved the streaming I/O onto another thread, so that mixing couldn't be delayed by a slow device.
  • Fixed a mutex leak on the PS3 when calling AIL_shutdown.
  • On the PS3, moved the internal Miles data tables into the code section to avoid overflowing the game's data section (fixes "relocation truncated to fit" errors on link).
  • Fixed a bug that could cause noise/distortion in certain high-amplitude source samples at faster-than-normal playback rates.
  • AIL_open_input now allocates a chain of 8 waveIn buffers, rather than 2.
  • On Windows, made the skip detection code use timeGetTime to avoid problems on AMD dual core machines.

Changes from version 7.0m to 7.0n (6-2-2006)

  • Added support for the Sony Playstation 3! All of the Miles functionality is present and works terrific!
  • Fixed a bug where the low-pass filter coefficients would be reset, even if you were selecting the same low-pass settings.
  • Fixed a bug where Voxware files could play back incorrectly when seeking to a non-frame boundary.
  • Fixed a memory leak in the chorus, delay, and flange filters.
  • Made the delay filter's buffer length shorter to save memory.
  • Fixed a problem with 8-bit multichannel output.

Changes from version 7.0L to 7.0m (5-8-2006)

  • Fixed a potential deadlock issue with the EAX output filters.
  • Fixed a bug that could cause position-update failures during listener movement when multiple DirectSound3D/EAX sounds were playing.
  • Fixed bug introduced with remnant-buffer optimization that could cause clicking when resampling compressed data.
  • Made some preliminary changes and additions for upcoming Ogg Speex support.
  • Added new All-Pass Filter, intended primarily for experimental use in phase-domain effects.
  • Added AIL_register_falloff_function_callback to allow the software mixer's 3D-distance falloff calculations to be overridden.

Changes from version 7.0k to 7.0L (4-21-2006)

  • Released final Miles 7.0 for MacOS! New to this platform is a Carbon Mach-O version of the library, so you can now use Miles with XCode and GCC. Support for Intel Macs coming soon.
  • Changed the mixer slightly to avoid 1-sample remnant buffers - sped up mixing of compressed formats very slightly.
  • Removed a dependency on a newer-than-necessary XMA library on the Xbox 360.

Changes from version 7.0j to 7.0k (4-18-2006)

  • Released beta of Miles 7.0 for MacOS.
  • Miles Sound Player now uses our MP3 frame-inspection API instead of a hardwired parser.
  • Fixed a potential source of crashes when selecting options in the Miles Sound Player that cause an MP3 file to be reloaded.
  • Added next_frame_expected member to MP3_INFO structure used by frame-inspection API.
  • Fixed the redistribution path in the streamer and multiflt examples so that they would work on Win64 and Mac.
  • Added a delay to the console examples, so that spinning on kbhit doesn't hog the CPU
  • Fixed a few files being installed to the wrong places on Win64.
  • Fixed a bug where downsampling an MP3 file by more than 2 to 1 when not using the resample filter (which you shouldn't do anyway) could cause the playback cursor to stop advancing.

Changes from version 7.0i to 7.0j (4-10-2006)

  • Added Ogg Vorbis support to the Miles Sound Studio and the Miles Sound Tools installations.
  • Made the Miles Sound Player decode the waveform data on a background thread (player plays immediately now).
  • Added a Win64 version of Miles! The entire Miles API is now available for Win64 and is completely compatible with Win32 Miles code. Thanks to AMD for their kind support of this porting effort!
  • MSS.h no longer includes any system header files (like windows.h or xtl.h).
  • Put memory fences around the interlocked functions in Miles (prevents some really obscure bugs).
  • The Miles Sound Tools includes both Win32 and native Win64 versions of the tools.

Changes from version 7.0h to 7.0i (3-15-2006)

  • Added optional Ogg Vorbis support! This new ASI decoder requires signing a special separate license with RAD before you can download it. It's available for all Miles platforms and is completely integrated into Miles. It uses a bit more CPU than MP3 and doesn't quite loop as well, but is a good option when you need low bit-rates.
  • Added DTS multi-channel output on the PS/2. This is a great-sounding output layer that takes very little CPU. Perfect for supporting PS/2s that are hooked up to home theaters. You must obtain permission from DTS before you can link with this output layer. Recommended for all PS2 developers.
  • Lots and lots and lots of internal changes to support the upcoming Windows 64-bit version of Miles.
  • Merged RIB attributes and preferences into a new concept called properties. There is now just one function to both retrieve and set properties, and properties are retrieved into a memory buffer instead of on the return stack. This means if you are setting filter preferences, then you will have to make a few simple code changes. Larger changes are necessary if you are interfacing directly to RIB plugins (or you have written your own); contact us for details on this change.
  • Big changes to the EAX 4 properties. You now set a particular EAX4 effect onto a slot directly (instead of the other way around). This is more consistent with what the hardware is doing and makes for a better API. If you have a lot of EAX 4 code, contact us and we'll help you update.
  • Fixed a bug where the low-pass filter cut off was based on the hardware DMA output rate instead of the sample rate.
  • Fixed a bug where the Xbox hardware low-pass filter wasn't being applied until the sound moved.
  • Fixed some occasional clicks when restarting a sample or rapidly changing the volume of a compressed digital sample.
  • Fixed a crash in Miles Sound Player with large compressed files.
  • OUTPUT_BIT_RATE property is now reported correctly by Voxware codecs.
  • Fixed a timer wraparound bug where the CPU usage would be measured incorrectly every 70 minutes.
  • Fixed the PS/2 file handle support, so that you can just pass in a file handle instead of a RAD_IOP_ASYNC_OPEN_DATA structure.
  • Built the Xbox 360 version with the April XDK (works with XDKs back to February).
  • Added new Gain Block Filter for generalized linear gain/nonlinear distortion effects.
  • PS2 and Xenon examples now start sounds at their intended 3D positions.
  • Fixed occasional trailing glitches when playing certain streams through hardware 3D voice filters on Win32 version.
  • AIL_mem_free_lock can now be used safely from within background callbacks on the PS2. The freed memory will be released during the next foreground call to AIL_mem_alloc_lock or AIL_mem_free_lock.

Changes from version 7.0g to 7.0h (12-27-2005)

  • Fixed a silly bug that caused distortion with the software low-pass filter.

Changes from version 7.0f to 7.0g (12-21-2005)

  • Made a few changes to the Xbox 1 XADPCM code to prevent clicks at the end of a stream and garbage after starvation.
  • Updated the Miles for PS2 build to link with CodeWarrior.

Changes from version 7.0e to 7.0f (12-14-2005)

  • Made the Windows 3D audio hardware filters respect the master digital volume level.
  • Added missing PS/2 example media files.
  • Tweaked the PS/2 example program, so that you can pass in the host paths on the command line.

Changes from version 7.0d to 7.0e (12-02-2005)

  • Added XMA playback to Xbox 360.
  • Added new demo for Xbox 360.
  • Switched to dcbt instead of xdcbt on Xbox 360 - no measurable performance difference and it is safer.
  • Added new demo for Sony PS2.
  • Added a complete SPU ADPCM voice API for Sony PS2 (now you can drop Multistream completely, if you'd like).
  • Added the ability to read from and to IOP and SPU memory with RAD_IOP. You can even stream MP3s out of IOP or SPU RAM!
  • Fixed CPU load-measuring on Sony PS2.
  • Fixed a bug in the DLS compressed-instrument decompressor.
  • Added a new DLS sample file.
  • Tweaked the distance-setting code on Xbox 1 to avoid pointless asserts in the Xbox system library.
  • MulitFlt.c example now demonstrates how to close a filter/driver binding.
  • DBTest.c example updated to demonstrate low-level double-buffering of .MP3 files.
  • FileHndl.c example updated to demonstrate how to stream from an existing file handle.
  • Fixed a bug that could cause looped streams to reset themselves under certain conditions.
  • Moved internal low-pass filter to post-resampling stage, for better compatiblity with .FLT filters

Changes from version 7.0c to 7.0d (9-23-2005)

  • First open beta of Miles for the Xbox 360! Only XMA playback remains to be done.
  • First open beta of Miles for the Sony PlayStation 2!
  • Fixed a bug that could cause low-level 125-Hz spurs in upsampled or downsampled sounds with the software mixer.
  • Fixed a bug that could cause a click when transitioning from unity-sampled playback rates to undersampled (pitch-up) rates.
  • Reduced zipper noise when changing parameters in certain filters (such as Parametric EQ).
  • Added "Mix" preference and attribute to all filters except Volume Ramp and Capture. This parameter ranges from 0.0 to 1.0, and determines the filter's degree of contribution to its own output signal. You can bypass a filter's effect altogether by setting its "Mix" parameter to 0.0. This will reduce the filter's CPU load significantly when the filter is not needed, while allowing its effect to be turned back on later without adding artifacts associated with filter initialization. Note that all filters with existing wet/dry mix parameters now use "Mix" instead. For instance, the phaser filter's "Phaser Mix" parameter is no longer present, having been renamed to "Mix".
  • Fixed a bug in the Compressor filter that caused incorrect operation with stereo source samples.
  • Added AIL_register_trace_callback function.
  • Fixed an incorrect pan value in the demo.c sample.
  • Documentation updated for PlayStation 2-specific library features.
  • Made a small change to allow redistribution files to be loaded from a Unicode path on Win32. Added a FAQ to describe how to do this.

Changes from version 7.0b to 7.0c (9-07-2005)

  • Fixed a bug in the DirectSound3D/EAX output filters that could cause voices of restarted samples to play at incorrect 3D positions.
  • Fixed a bug in the DirectSound3D/EAX output filters that could cause voices to stop playing under certain conditions.
  • Added CPU usage display to the examms example. This readout shows the load placed on a single CPU by the MSS background service thread.

Changes from version 7.0a to 7.0b (8-02-2005)

  • New unified 3D/2D API -- no more H3DSAMPLES! EAX and DirectSound3D applications now work with HSAMPLEs, giving them access to the entire Miles digital audio API.
  • Added support for discrete multispeaker surround-sound output, including 4-channel, 5.1, 6.1, 7.1, and 8.1 formats. You can use our software multichannel provider for more voices and maximum consistency, or use EAX/DirectSound3D for hardware-accelerated effects.
  • DSP filters may now be stacked up to eight levels deep. AIL_filter_sample_attribute and AIL_set_filter_sample_preference have been deprecated in favor of AIL_sample_stage_attribute and AIL_set_sample_stage_preference, respectively. These functions take a constant from DP_FILTER_0 (formerly the only available per-sample filter slot) to DP_FILTER_7 (the last of eight available slots in the new version).
  • Added two new classes of filters. 'Matrix' filters perform postmix processing for output formats such as Dolby Surround and SRS Circle Surround. 'Voice' filters actually replace the Miles mixer itself, performing their own hardware buffer management on a per-voice basis. All of the EAX/DirectSound3D functionality previously implemented in M3D providers is now based on voice filters. Both matrix- and voice-output filters are installed automatically when AIL_open_digital_driver is called with the appropriate enum value from MSS_MC_SPEC.
  • All platforms, including Xbox and DOS, now support DSP filters.
  • New digital audio loop editor added to Miles Sound Player lets you generate seamless loops even within MP3 files!
  • Added support for SRS Circle Surround(R). This is a Dolby-compatible matrix provider that offers discrete rear-channel positioning on supported receiver hardware.
  • Removed some obsolete, unmaintained, and/or little-used 3D providers (RSX, QMixer, A3D).
  • Replaced exam3d.exe and con3d.exe example programs with more-general examms.exe example.
  • Complete rewrite of EAX/DS3D code to support unified API. Improved performance due to more-efficient buffer reuse.
  • AIL_HWND ignores WS_DISABLED windows when searching for a window associated with the current process.
  • Several issues with the DOS version were addressed (the timer interrupt stack size was bumped from 2K to 32K, the DP_DEFAULT_MERGE provider is now set correctly, sample pipeline filters are now supported, SSE support has been disabled for DOS extender compatibility, and ASIFILE works correctly with MP3 decoder)
  • Miles Fast 2D provider moved into core library. (All drivers offer 3D distance/directional attenuation now, enabled by calling AIL_set_sample_3D_position on an HSAMPLE.)
  • MP3 frame headers are now checked for consistency against the most recent valid frame, rather than the first frame in the file (which may have been corrupted or incorrectly-detected).
  • Added a frame-level MP3 disassembly utility to the Miles Sound Studio. The disassembler is accessed via the File Info button (formerly File Type).
  • Added frame-level MP3 inspection to the API via the AIL_inspect_MP3 and AIL_enumerate_MP3_frames functions.
  • ID3v2 tags in the middle of an MP3 file are now handled properly.
  • MP3 frames with insufficient data now generate silence rather than simply being skipped (improves robustness in subblock loops).
  • Accumulated MP3 output data (and its associated filter state) is no longer discarded during looping (only during normal seek operations, e.g., in response to AIL_set_sample_position).
  • Removed external reverb filters. The core library's reverb implementation offers a superset of the removed filters' functionality.
  • Removed Lagrangian resampling filter (not competitive with internal resampler).
  • Made several changes to the internal API for pipeline filter providers to support multichannel build buffers and postmix processors. Third-party FLT providers will need to be revised for use with MSS 7. Added inline helper functions to imssapi.h for ease of maintenance.
  • Always perform predelay calculations to position the reverb tail pointer correctly, even when wet level is zero.
  • Doppler calculations now use cosine scaling to discriminate against sources moving perpendicular to source-listener axis.
  • Removed EAX 1 support, due to EAX 1's lack of standardization, feature-poor control API, buggy OEM drivers, and the widespread presence of EAX 2-compatible hardware. All EAX 1 applications should migrate to EAX 2 or (preferably) discrete software-mixing configurations.
  • Fixed various bugs in the EAX providers, including an array-overflow bug in EAX 4 and incorrect 3D auto-attenuation flag control in EAX 2/3. Significant changes were made to the way occlusion, obstruction, and exclusion are applied to dry and wet levels in the various providers, with the goal of harmonizing their behavior across providers to the greatest extent possible. Some preferences such as EAX_REVERBMIX are now under API control, and were removed. This means that EAX applications optimized for use with Miles 6 may need to be re-tweaked when upgrading to Miles 7!
  • Added auto_3D_wet_atten parameter to AIL_set_sample_3D_distances.
  • For improved compatibility with certain streaming applications, AIL_load_sample_buffer no longer automatically starts playback. You must call AIL_start_sample yourself, after submitting either one or two valid buffers. (AIL_start_sample no longer restarts playback of double-buffered samples that are already playing, so there's no need to check the sample's playback status when calling AIL_start_sample after AIL_load_sample_buffer.)
  • Removed AIL_set_sample_type and moved its parameters to AIL_init_sample. It is no longer necessary to call AIL_init_sample prior to AIL_set_sample_file, AIL_set_named_sample_file, or AIL_set_sample_info.
  • Removed the AIL_allocate_file_sample and AIL_register_EOF_callback functions. Use AIL_set_sample_file or AIL_set_named_sample_file instead.
  • Removed the (previously-deprecated) AIL_waveOutOpen function. Use AIL_open_digital_driver instead.
  • Fixed a bug that could cause AIL_open_digital_driver or AIL_waveOutOpen to fail when using waveOut.
  • Fixed a bug that could cause a short glitch when restarting playback of an MP3 file.
  • We no longer allow a sample's state to reach SMP_DONE if an ASI decoder still has some data in its output buffer. This fixes a bug that could cause the last few kilobytes of output data from an MP3-based sample or stream to be lost.
  • Two Win32-specific preferences, DIG_PREFERRED_WO_DEVICE and DIG_PREFERRED_DS_DEVICE, have been added to force AIL_open_digital_driver to use a specific waveOut device ID or DirectSound LPGUID. These preferences take the place of the dwDeviceID parameter in AIL_waveOutOpen. Most applications should leave these preferences at their default values of WAVE_MAPPER and NULL, respectively.
  • Added a new preference, DIG_LEVEL_RAMP_SAMPLES, which determines the number of samples over which volume level changes will be ramped in at each software-mixing interval. With this feature, all software-mixed platforms will experience significantly less unwanted clicking and "zipper noise" during changes to volume control levels and 3D positions.
  • Fixed a bug which could introduce clicking artifacts on samples whose playback rates are swept through unity. This fix improves Doppler-effect quality significantly in some cases.
  • Renamed AIL_set_3D_room_type and AIL_3D_room_type to AIL_set_room_type and AIL_room_type, respectively. AIL_set_digital_master_room_type has been removed. The room-type functions are now available even for samples that aren't undergoing 3D positioning by MSS.
  • Likewise, AIL_set_3D_sample_occlusion, AIL_set_3D_sample_obstruction, AIL_set_3D_sample_exclusion, AIL_3D_sample_occlusion, AIL_3D_sample_obstruction, and AIL_3D_sample_exclusion have been renamed to AIL_set_sample_occlusion, AIL_set_sample_obstruction, AIL_set_sample_exclusion, AIL_sample_occlusion, AIL_sample_obstruction, and AIL_sample_exclusion.
  • Removed the concept of the 3D HPROVIDER from the API. The functions AIL_set_3D_distance_factor, AIL_set_3D_doppler_factor, AIL_set_3D_rolloff_factor, AIL_set_room_type, AIL_3D_distance_factor, AIL_3D_doppler_factor, AIL_3D_rolloff_factor, and AIL_room_type now take an HDIGDRIVER rather than an HPROVIDER. AIL_enumerate_3D_providers, AIL_enumerate_3D_provider_attributes, AIL_set_3D_provider_preference, AIL_3D_provider_attribute, AIL_find_3D_provider, AIL_open_3D_provider, and AIL_close_3D_provider have been removed.
  • Removed the AIL_set_3D_speaker_type function and the MILES_SPEAKER_TYPE definitions. Speaker types are either specified by the end user via their Windows control panel or OEM configuration applet, or are implicit in the MSS channel specification passed to AIL_open_digital_driver (e.g., MSS_MC_51_DISCRETE or MSS_MC_STEREO).
  • Removed the H3DSAMPLE type from the API. Most functions that formerly operated on H3DSAMPLEs were removed, including AIL_3D_sample_attribute, AIL_3D_sample_length, AIL_3D_sample_loop_count, AIL_3D_sample_offset, AIL_3D_sample_playback_rate, AIL_3D_sample_status, AIL_3D_sample_volume, AIL_allocate_3D_sample_handle, AIL_end_3D_sample, AIL_register_3D_EOS_callback, AIL_release_3D_sample_handle, AIL_resume_3D_sample, AIL_set_3D_sample_info, AIL_set_3D_sample_loop_block, AIL_set_3D_sample_loop_count, AIL_set_3D_sample_offset, AIL_set_3D_sample_playback_rate, AIL_set_3D_sample_preference, AIL_set_3D_sample_volume, AIL_start_3D_sample, and AIL_stop_3D_sample.
  • Removed AIL_active_3D_sample_count.
  • Removed the H3DPOBJECT type, as well as the AIL_auto_update_3D_position, AIL_open_3D_listener, AIL_close_3D_listener, AIL_open_3D_object, AIL_close_3D_object, AIL_3D_user_data, and AIL_set_3D_user_data functions. The remaining functions which took H3DPOBJECTs, including AIL_3D_orientation, AIL_3D_position, AIL_3D_velocity, AIL_set_3D_orientation, AIL_set_3D_position, AIL_update_3D_position, AIL_set_3D_velocity, and AIL_set_3D_velocity_vector have been replaced with versions specific to HSAMPLEs (AIL_sample_3D_orientation, AIL_sample_3D_position, AIL_sample_3D_velocity, AIL_set_sample_3D_orientation, AIL_set_sample_3D_position, AIL_set_sample_3D_velocity, AIL_set_sample_3D_velocity_vector) and HDIGDRIVERs (AIL_listener_3D_orientation, AIL_listener_3D_position, AIL_listener_3D_velocity, AIL_set_listener_3D_orientation, AIL_set_listener_3D_position, AIL_update_listener_3D_position, AIL_set_listener_3D_velocity, AIL_set_listener_3D_velocity_vector).
  • Renamed the remaining AIL_3D_sample...() / AIL_set_3D_sample...() functions to AIL_sample_3D...() / AIL_set_sample_3D...() to reflect the fact that 3D positioning is now just another property of an HSAMPLE, rather than a feature implemented by a separate '3D sample' type. The newly-renamed functions are AIL_set_sample_3D_distances, AIL_sample_3D_distances, AIL_set_sample_3D_cone, AIL_sample_3D_cone, AIL_set_sample_3D_position, AIL_set_sample_3D_velocity, AIL_set_sample_3D_velocity_vector, AIL_set_sample_3D_orientation, AIL_sample_3D_position, AIL_sample_3D_velocity, AIL_sample_3D_orientation, and AIL_update_sample_3D_position. Note that an HSAMPLE's 3D properties are ignored by MSS until the application requests 3D positioning support by calling AIL_set_3D_position! Once enabled for a given HSAMPLE, 3D positioning can be disabled by releasing and reallocating the HSAMPLE, or by calling AIL_init_sample, AIL_set_sample_file, AIL_set_named_sample_file, or AIL_set_sample_info.
  • Removed AIL_3D_sample_effects_level and AIL_set_3D_sample_effects_level. Reverb effects for all samples (whether or not they're 3D-positioned) are now controlled by AIL_set_sample_reverb_levels. Note that the per-sample wet mix defaults to 0.0, so at least one call to AIL_set_sample_reverb_levels is mandatory before you'll be able to hear any reverb/room effects on any given sample.
  • Added AIL_DLS_sample_handle and AIL_stream_sample_handle functions to allow access to the HSAMPLE associated internally with an HDLSDEVICE or HSTREAM. This allowed us to remove AIL_DLS_set_reverb_levels, AIL_DLS_get_reverb_levels, AIL_stream_reverb_levels, AIL_set_stream_reverb_levels, AIL_DLS_processor, AIL_set_DLS_processor, AIL_stream_processor, AIL_set_stream_processor, AIL_stream_playback_rate, AIL_set_stream_playback_rate, AIL_set_stream_low_pass_cut_off, AIL_stream_low_pass_cut_off, AIL_set_stream_volume_pan, AIL_stream_volume_pan, AIL_filter_stream_attribute, AIL_set_filter_stream_preference, AIL_filter_DLS_attribute, and AIL_set_filter_DLS_preference.
  • Added AIL_set_speaker_configuration and AIL_speaker_configuration.
  • Added AIL_set_listener_relative_receiver_array and AIL_listener_relative_receiver_array. These functions are reserved for future use, and are undocumented at present.
  • Added AIL_set_speaker_reverb_response and AIL_speaker_reverb_response.
  • Added AIL_set_sample_channel_levels and AIL_sample_channel_levels.
  • Added AIL_digital_output_filter, AIL_enumerate_output_filter_driver_attributes, AIL_output_filter_driver_attribute, AIL_set_output_filter_driver_preference, AIL_enumerate_output_filter_sample_attributes, and AIL_enumerate_sample_stage_attributes. (Note that sample-level attribute and preference values for voice output filters may be accessed by specifying DP_OUTPUT in calls to AIL_sample_stage_attribute and AIL_set_sample_stage_preference. Matrix output filters do not support per-sample attributes and preferences.)
  • AIL_open_filter now returns -1 (rather than 0) if the filter HPROVIDER was already associated with the specified HDIGDRIVER.
  • Release candidate for version 7 on Windows and Xbox.
  • Major speed optimizations over version 7.0a - 300% faster multichannel mixing, 200% faster DSP effects.
  • Xbox can play now 3D audio on a 2D digital driver by using the pan and volume spacialization code from Win32. This means you are no longer restricted to the Xbox's 64 3D audio voices.
  • Xbox can now use the Miles software DSP filters. The only restriction is that you can't apply the software DSP filters to Xbox ADPCM voices (since the hardware decompresses them).
  • Renamed the AIL_speaker_reverb_response to AIL_speaker_reverb_levels - this function now allows you to set the master volume level for both wet and dry, so you can use it to set balance levels of each speaker.
  • Replaced the mono/stereo delay filters with a single unified delay filter that can serve both purposes.

Changes from version 6.6h to 7.0a (5-16-2005)

  • Beta of the new 7.0 system.

Changes from version 6.6g to 6.6h (12-10-2004)

  • Fixed a small memory leak in 3D sample handle allocation when the buffer format changed (introduced in 6.6g).
  • Fixed a sound clip in the RSX provider when playing 8-bit sounds.

Changes from version 6.6f to 6.6g (12-07-2004)

  • Added a new DSP filter to allow you to smoothly ramp up or down volume over time. You can ramp your volumes on a sample by sample basis over any length of time with 3 lines of code. Also added a FAQ explaining how to use this new filter.
  • Added a new utility function, AIL_find_filter, to quickly and easily locate a filter by name. This just saves you from having to do the enumeration yourself.
  • Added another utility function, AIL_find_3D_provider, to quickly and easily locate a 3D provider by name. Like AIL_find_filter, this just saves you from having to do the enumeration yourself.
  • Optimized the AIL_set_3D_sample_data functions so that a DirectSound buffer is only reallocated if the sound format has changed. This can double the speed of these common functions on most hardware.
  • If the format of a sound buffer didn't change in AIL_set_3D_sample_data, then we no longer reset the position, orientation, volume, etc. of the 3D sample. We no longer do this because you will usually immediately change these settings anyway, and it makes a big difference in setup time. If you were previously relying on the settings to be cleared, then you can clear them by hand, or you can release and then reallocate the 3D handle.
  • Fixed a bug in the DirectSound hardware 3D providers where you could allocate one more 3D sound handle than the hardware could play. No sound would ever play on this handle, so you could unknowingly have had sounds that were never being played. Due to this fix, you may want to double check your AIL_allocate_3D_sample_handle logic to make sure it can handle a null return value (which will now happen if you exceed the sound card's internal buffer limit).
  • Fixed a bug in the upsampling filter (on PC and Mac) that caused clipping. This would also affect the Miles Fast 2D providers as well.
  • Fixed a bug when using the upsampling filter on ACPCM or MP3 compressed data where one sample at the end of each decompressed buffer might be skipped (this causes a periodic clicking at very slow playback rates).
  • Clear the previous sample filter values whenever you restart a sample playback (to avoid a click from the filter if you previously stopped it in the middle of a sound).
  • We now exclude disabled top level windows in our automatic HWND detection code (DirectSound requires an HWND) - this avoids occasionally identifying hidden application message windows.

Changes from version 6.6e to 6.6f (10-31-2004)

  • Tweaked the Audigy bug handling and detection again (sigh).
  • Added AIL_set_sample_info to the 2D digital sound system to be orthogonal to the 3D AIL_set_3D_sample_info function.
  • Fixed a bug where the MP3 decoder DLL could crash if it was unloaded twice (if there were two copies of the DLLs accidentally loaded).
  • We no longer reload the RIBs when you specify "." for the redistribution path.
  • We no longer auto-register AIL_shutdown to be called in the application's atexit handler. This was convenient but caused too many wacky linker bugs. You have to do this yourself, if you want this behavior now.
  • Fixed AIL_stream_position to be much more accurate (added thread protection) and to give accurate values around loop points.
  • Fixed a bug in the streaming system where if you jumped to the end of an ADPCM sound image, then we would pad out the buffer even though we never read the unpadded final ADPCM block. This would cause looping ADPCM streams to play garbage if you seeked off the end.
  • Fixed a bug in the DirectSound code where, if you cranked up the DIG_DS_MIX_FRAGMENT_CNT preference to maximum, then you could overwrite the play cursor which would cause sound glitching.

Changes from version 6.6d to 6.6e (10-23-2004)

  • Added some code to work around yet another Creative Labs driver bug. This Audigy 2 driver bug is identical to the SBLive bug from several years ago - after ten hours or so of looping, a DirectSound buffer will suddenly stop reporting buffer position changes. We now watch for any time positions stop changing for longer than 128 ms, and upon this unhappy event, we reset the buffer. This gives a little click of sound (once every ten hours), but at least the audio continues playing.
  • Changed some logic to allow streams to be closed inside an end of stream callback (which we don't really recommend anyway).

Changes from version 6.6c to 6.6d (08-17-2004)

  • Set the thread stack size lower on the Xbox version.
  • Fixed a rare bug that could cause a divide overflow crash when looping an MP3 stream that ended precisely on an MP3 frame boundary.
  • Fixed a bug on the Xbox version where setting the velocity would change the position instead.
  • Limit the number of Xbox streaming buffers that are allocated to never be more than the number of HSAMPLEs that are allocated.
  • Fixed a stupid editting error that causes the ADPCM decompressor to fail on MacOS.
  • Checked for the digital driver being NULL in several of the sound functions for safety.
  • Made the EAX4 provider automatically turn on "environment mode" when selecting the room reverb filter.

Changes from version 6.6b to 6.6c (05-18-2004)

  • Added all new EAX 4 support. Nice, clean, streamlined support for the otherwise complicated EAX 4 API, along with a new simple example application to show you how to use it.
  • Added some thread protection to the DX calls in the DirectSound3D based 3D providers to avoid rare crashes when making 3D sound calls from a background thread or timer.
  • Fixed a free buffer problem that eventually led to crashes when streaming files on the Xbox.

Changes from version 6.6a to 6.6b (04-18-2004)

  • Fixed a SMP crashing bug on MacOS.
  • Optimized the 16-bit sample clippers on MacOS.
  • Optimized the 64-bit divider on MacOS.

Changes from version 6.5h to 6.6a (03-31-2004)

  • Major optimizations on the MP3 decoder - added SSE support and did lots of memory and code generation tweaks to improve playback speed. On P4s, MP3 decompression is 1.9 times as fast. On P3s, we are 1.7 times as fast. The fastest MP3 decoder is now almost twice as fast!
  • Fixed MP3 files with ID3 tags being clipped off at the end.
  • Fixed AIL_quick_unload to avoid a crash on fast machines when closing a MIDI with DLS sample.
  • Made streaming playback begin immediately in AIL_start_stream, instead of the next time the background thread executed.
  • Fixed a bug when pausing and resuming when using the low-level stream APIs where the playback would never unpause. This could cause the high-level streaming services to stall if pausing a stream immediately after playing it on a very fast machine.
  • Tweaked thread latencies on Windows and Xbox so that DirectSound is polled less often.
  • Default memory alignment is now 32-byte boundaries for SSE.
  • Updated CPU detection to detect SSE first, then 3DNow, and then then MMX.
  • Fixed some floating point epilson checks to avoid overflows in DirectSound volume setting functions.
  • Fixed the Xbox 5.1 support, so that the right right speaker is handled correctly.
  • Fixed the Xbox version, so that it wasn't always logging debug dumps to the hard drive.
  • Fixed streaming of Xbox ADPCM files.
  • Fixed crash on Xbox when decoding multiple IMA ADPCM or MP3 files at once.
  • Turned the Xbox sample headroom values back on, so that 2D and 3D volumes are better balanced.
  • Fixed the MP3 data tables, so they weren't modified in place (so you could re-init the library without reloading the DLL).
  • Fixed a bug in the MP3 decoder where perfectly tonal sound samples could have a periodic volume drop.
  • Added a new preference "DirectSound Sample Buffer" to obtain the DirectSound handle to a H3DSAMPLE.
  • Brought the Mac version up to date with the PC and Xbox versions.

Changes from version 6.5g to 6.5h (11-25-2003)

  • Fixed a problem where denormal floating pointing values were leaking into the IIR filter (which caused CPU use to be way too high on P4s when using the software EAX filter).

Changes from version 6.5f to 6.5g (11-01-2003)

  • First release of Miles for Xbox! Miles for Xbox maps the entire Miles API onto the powerful Xbox hardware. Without changing your code, you'll get hardware acceleration of almost all Miles features!
  • Fixed a link setting that prevented Visual Studio 6 from linking Miles.
  • Improved the performance of the DLS synthesizer by not mixing instruments that have gone silent. This can double the performance of some DLS sequences.
  • Increased the default number of simultaneous DLS voices allowed from 32 to 64.
  • Added the RegisterRIB function to load the MP3 and Voxware codecs in the static library versions of Miles (Xbox and DOS).

Changes from version 6.5e to 6.5f (10-09-2003)

  • Added "EAX property set" and "EAX sample property set" attributes to the EAX providers, so that you can hook to EAX directly if necessary.
  • Toggle EAX "auto" mode when using -1 for the mix level on EAX 2 and 3 - this lets EAX 1 be more closely emulated.
  • Made the effects level only control the wet level on EAX 1 which makes it more consistent with software and EAX 2+.
  • Fixed crash when calling AIL_process_digital_audio if audio was already playing.
  • Force compatibility to DirectSound 3 in the 2D system (so we work on NT4 again).
  • Fixed a crash when initializing waveOut mode on NT4.
  • Fixed a multithreaded deadlock on MacOS X.

Changes from version 6.5d to 6.5e (03-17-2003)

  • Worked around a multi-threaded bug in the system function, timeGetTime, that would cause Miles to use too much CPU.

Changes from version 6.5c to 6.5d (02-12-2003)

  • Worked around a bug in the SBLive drivers where positions were moving backwards (which caused periodic sound drop outs).
  • Changed channel locking logic so that you can redundantly lock a channel in a MIDI stream.
  • DLS banks other than 0 are now handled properly.
  • Fixed a bug in the channel-lock controller (114) code that could cause lock failure in some sequences.
  • All MIDI channels from 1-16 are now available for dynamic assignment by controller 114 and AIL_lock_channel. This change allows more complex sequences to be overlaid, but eliminates support for channel-locking on non-General MIDI synthesizer platforms.
  • Fixed some crashes when playing bad MP3 data (more bulletproofing of the decoder).
  • Change the DirectSound 3D providers not to reset the speaker type to stereo on startup.
  • Switched to Perforce for source code control.
  • Switched to building with MSVC 7 on Windows.
  • Integrated the Linux changes into the main Miles tree (official release soon).
  • Switched to building internally with our internal make utilities. We now generate complete batch files to build Miles with no fuss.

Changes from version 6.5b to 6.5c (07-19-2002)

  • Fixed a bug in the Miles Fast 2D and the Dolby Surround providers where the playback rate wasn't being set correctly.
  • First version of 6.5 for the Macintosh!
  • Fixed a crash in the digital input API when running on MacOS X.
  • On the Mac, fixed a crash when the Miles library was placed in a folder more than 127 characters long (now limited to 255 and doesn't crash in any case).
  • On the Mac, fixed a bug where 3D samples could get stuck playing with the SMP_PLAYING flag always on.
  • Switched to using critical sections on MacOS X. Fixes lots of deadlock conditions that could occur on multi-CPU machines. Uses the timer system from Bink.
  • Fixed a bug in the resamplers on the Mac where stereo files could sometimes bleed a bit from the right channel into the left.
  • Now use UpTime in Carbon instead of Microseconds (faster on MacOS 9).
  • On the Mac, made AIL_mem_use_malloc and AIL_mem_use_free exported functions.
  • On the Mac, better quality resampling of ADPCM and MP3 streams.
  • Now use a 20 ms mix ahead on the Mac for less CPU use.
  • On the Mac, use more descriptive names for all of the Miles redistributable files.

Changes from version 6.5a to 6.5b (07-07-2002)

  • Fixed a bug in the Miles Fast 2D and the Dolby Surround providers where the same H3DSAMPLE was always returned from AIL_allocate_3D_sample_handle.
  • Fixed a bug in AIL_stream_volume_pan where the volume levels where being incorrectly returned.
  • Fixed a bug where the debug log could sometimes get truncated.

Changes from version 6.1c to 6.5a (05-30-2002)

  • Moved the software EAX reverb engine directly into the Miles mixer and massively optimized it. You can now add global reverb for essentially no CPU hit at all (0.25% - one forth of one percent) per sample! Since it is built into the mixer, you can add software EAX reverb on digital streams or the DLS songs as well.
  • Moved the low-pass filter into the Miles mixer and did massive optimizations. You can now use low-pass filtering for about 0.33% (one third of one percent) per sample.
  • Merged the digital volume and pan functions and made them accept float values that are linear in loudness (not amplitude). That means that 0.5 is 10 dB down (vs. 6 dB in a linear amplitude system). The pan is now a power pan compatible with DLS - the left and right levels are adjusted to give a balanced total volume as the panned sample moves from one speaker to the other.
  • Added direct volume level functions that accept a specific float level for the left and right speakers from 0.0 to 1.0. These direct volume functions are linear in amplitude space (0.5 is 6 dB down).
  • Added a new Creative EAX 3 provider (Thanks Carlo).
  • Added support for exclusion (a new EAX 3 setting) control in all of the providers (emulated where necessary) and at the API level.
  • Added a new Dolby Surround DSP filter. You can now set the front to back pan level on Dolby Surround speaker systems on samples, streams or DLS songs.
  • Added new 5.1 and 7.1 speaker system flags. Fixed the default mode of the DirectSound3D providers always using 2-speakers.
  • Don't perform mixing at all on samples whose volumes are zero - speeds up the 3D providers when the 3D sample is beyond the maximum distance.
  • Mix twice as far on emulated DirectSound drivers to smooth skipping problems.
  • When automatically choosing between DirectSound and waveOut, if emulated DirectSound works, but waveOut doesn't work, then flip back to emulated DirectSound even though it may skip.
  • Added a time-out in the waveOut support so buggy drivers don't lock up Miles.
  • Merged all of the digital filters into one DLL instead of 18 (smaller and faster to load - not to mention 17 fewer files in the redistribution directory).
  • Merged all of the EAX 3D providers into one DLL, all of the A3D providers into one DLL, all of the DirectSound3D providers into one DLL, all of the DirectX 7 3D providers into one DLL and all of the Miles software providers into one DLL (again this is smaller and faster to load).
  • Fixed a bug in the DLS synthesizer where songs could overrun after a certain length of time (leading to small pops).
  • Fixed a bug in the DLS synthesizer where notes played exactly on frequency could be dropped.
  • Switched to using a new voice re-allocation strategy in the DLS synthesizer when running out of voices.
  • Changed the envelope shaping in the DLS synthesizer to be linear in amplitude space (vs. the seemingly more correct linear in dB).
  • Upped the simultaneously voices in the DLS synthesizer from 24 to 32.
  • Fixed a small memory leak in the 3D system when a provider fails to open another 3D sample (Thanks Jeff).
  • Fixed a bug where using the non-async file reading callbacks where they could be called at interrupt time on MacOS and DOS (leading to a crash) (Thanks John).
  • Fixed a bug where requesting the length of a quick audio handle could cause the next audio handle to prematurely end.
  • Fixed a steathly bug where playing a non-MP3 stream directly after an MP3 stream at exactly the right moment could cause a crash (Thanks James).
  • Fixed a goofy bug in the ASIFile example where the files were being converted only 4 bytes at a time.
  • Dropped Win32s support (Win32 on Win16).
  • Switched to not calling GlobalLock on Win32 to support some memory debugging systems.
  • Added the "Mute at max" preference to the Miles software 3D providers and the DirectSound 3D based providers. This allows you to control whether sounds are muted at the maximum distance (the default) or just stop fading out at the maximum distance.

Changes from version 6.1b to 6.1c (10-15-2001)

  • Added the new 3D functions: AIL_set_3D_rolloff_factor, AIL_set_3D_doppler_factor, and AIL_set_3D_distance_factor.
  • Fixed a bug in the DLS synth where MIDI notes could sometimes get shut off when a song looped.
  • Added support for MP3 files with ID3 v2 headers. ID3 v2 headers can be up to 64K, so you will usually want to avoid them for space considerations.
  • Fixed a subtle bug in the PC downsampling mixers, where the audio could be quite noisy and crackly when downsampling by very small factors.
  • Made optimizations to the PC ADPCM and 8-bit sound mixers.
  • Added a workaround in the PC Miles timer code for buggy motherboards that advance the QueryPerformanceCounter incorrectly under heavy loads. Also added a check to prevent the timer from ever running backwards.
  • Fixed a bug in PC Miles where you couldn't restart Miles with the quick API.
  • Fixed a bug where AIL_quick_ms_length wouldn't return the correct length unless the sound was playing.
  • Added a few changes to the RIB subsystem so that RIBs are reference counted.
  • Used the special exception code on NT to label the Miles background threads (easier to see what threads belong to Miles).
  • Fixed a bug in the PC timer code where if you released a timer inside a timer callback, the callback might be called again.
  • Fixed a bug when playing waveOut audio on NT4 with an SBLive where the sound would skip and stutter.
  • Fixed a bug when playing waveOut audio and you released and then reacquired the digital sound handle.
  • Added support for overriding the Miles memory allocation routines under Win32.
  • Fixed a bug where the Miles Sound Studio would crash on a MIDI or DLS Dump.
  • Fixed a crash bug in the RSX provider when shutting down while running on waveOut drivers.

Changes from version 6.1a to 6.1b (09-06-2001)

  • Mac MP3 decoder has been completely rewritten in PPC assembly. It is 20% faster than the old decoder.
  • Switched to a shorter mix-ahead for lower latency on the Mac.
  • Fixed a crash when streaming very short MP3 files on the Mac.
  • Fixed a rare crash when streaming files on the Mac.
  • Fixed a crash in the MIDI to XMIDI converter on the Mac.

Changes from version 6.0m to 6.1a (03-06-2001)

  • First official MacOS version! PC and Mac versions fully synched.
  • All new sound mixers - in some cases up to 3 times faster! Also includes much higher quality resamplers (fully linearly interpolated vs. approximate).
  • Fixed crash when running under waveOut.
  • More tolerant of bad MP3 data (keep playing whenever possible and fewer potential crashes).
  • Fixed a bug in the Miles Fast 2D and Dolby Surround providers where some samples beyond the maximum distance never finish playing.
  • Added the AIL_set_async_file_callbacks function. This allows you to replace the file IO functions used by the streaming API using asynchronous IO (usually only used on MacOS or Win NT).
  • Plain MP3 files inside of a packed file can now be opened by the streaming API without having to wrap a wave header around the data. To do this, pass in the file handle as you would normally do only now add a comma, followed by the length of the MP3 data. For example, if you wanted to stream out of file handle 5, for 32768 bytes, use "\\\\5,32768".
  • Fixed a bug in the voice chat client example where the application could crash on opening.
  • Fixed a bug in the exporting of the AIL_update_3D_position and AIL_auto_update_3D_position functions.
  • Miles no longer includes pre-built 16-bit Windows DLLs - they must be built on the developer's machine (mainly because the 16-bit Microsoft C compiler doesn't work on my Win2K machine any longer).

Changes from version 6.0k to 6.0m (11-12-2000)

  • All new documentation - includes online and offline versions!
  • Most examples have been rewritten to make them easier to understand.
  • Added the AIL_open_digital_driver/AIL_close_digital_driver and AIL_open_XMIDI_driver/AIL_close_XMIDI_driver functions. These functions work on all Miles platforms and should now be used instead of AIL_waveOut* and AIL_midiOut* which were Windows-only and are now deprecated.
  • Miles now allows all ASI formats to wrapped in a wave file. Each ASI exports a wave format tag that tells Miles what ASI decoder to use.
  • Renamed the AIL_DLL_verion function to AIL_MSS_version.

Changes from version 6.0J to 6.0k (10-22-2000)

  • MP3 streams no longer cause audio artifacts at the wrapping of a sub-block.
  • The current playback position in an MP3 stream is now correctly reported after a sub-block loop seek.
  • Made the MP3 decoder more tolerant of bad MP3 streams.
  • Renamed the AIL_input_info function to AIL_get_input_info.

Changes from version 6.0i to 6.0J (10-04-2000)

  • Added the AIL_set_file_callbacks function. This allows you to replace the file IO functions used by the streaming API and AIL_file_read.
  • Added the AIL_set_stream_processor and AIL_set_DLS_processor filter installation functions.
  • Fixed a couple stream API deadlock/crash possibilities (when running in a multithreaded game).
  • Fixed an atexit link warning when building with the non-static C runtime or a non-Microsoft C compiler.
  • Fixed a tricky DLS timer aliasing bug when running under Win2K.
  • Changed the size parameters to AIL_extract_DLS to be U32s instead of S32s.

Changes from version 6.0h to 6.0i (08-17-2000)

  • Made MSS const-clean! Most source files changed to handle the new const action.
  • Fixed a shutdown crash when starting up and shutting down the system multiple times while streams are playing.
  • Fixed a crash in the mono delay, stereo delay and reverb 1 filters where memory was freed out of order.
  • Fixed a granularity problem when seeking with milliseconds in an uncompressed sound stream.
  • Fixed the sub-block looping on streams to allow -1 for the end of the stream.
  • Limited waveOut latency to more reasonable maximum values - should have much lower latency on NT 4 with newer sound cards.
  • Renamed the internal STREAM_TYPE structure to avoid collisions in the MMSYSTEM.H Windows header file.
  • Added the new function RIB_find_files_provider which allows you to search for multiple file formats at once (when you need a specific input and output format, for example).

Changes from version 6.0g to 6.0h (06-08-2000)

  • Improved the streaming playback performance when multiple streams are playing at once or when playing a stream that comes close to fully exhausting the IO bandwidth of the streaming device.
  • Force call to AIL_shutdown from an atexit handler to insure Miles is always closed.
  • Lock far fewer Miles functions for better performance on multiple CPU machines.
  • Fixed a crash problem in the console applications if you hit Control-Break to exit.
  • Internally meter AIL_serve checks so that the buffer status is only checked every 10 ms.

Changes from version 6.0f to 6.0g (06-01-2000)

  • Tweaked all of the software EAX settings to much closer match hardware EAX.
  • Fixed setting the playback position on very short streams.
  • Fixed a crash in AIL_set_DirectSound_HWND if a hardware 3D provider is installed.
  • Fixed a crash when closing the input API under Windows 2000.
  • If no default HWND is found, MSS now uses the current foreground window with DirectSound (which fixes some problems in NT console windows).

Changes from version 6.0e to 6.0f (04-24-2000)

  • Removed the Sleep in AIL_serve which could cause Smacker to skip on Windows 2000 when running in waveOut mode.

Changes from version 6.0d to 6.0e (04-20-2000)

  • Changed AIL_stream_close to not shutdown the background thread (which, under Windows 98 in the debugger, takes so long that the sound can skip). The stream servicing thread is now closed at shutdown time.
  • Re-validate the HWND when re-opening a digital device (to work around a bug in the SBLive drivers which crashed on an invalid HWND).

Changes from version 6.0c to 6.0d (03-21-2000)

  • Fixed a really-well hidden bug that could cause the MP3 *encoder* to lock up when the FPU state was set to a non-default mode.
  • Fixed a deadlock that could occur when closing a stream on a multiple CPU machine.
  • Fixed the background of some of the controls in the sample apps under Win2K.
  • Fixed a crash in the RSX provider when setting the velocity before setting the sample's audio data.

Changes from version 6.0b to 6.0c (02-21-2000)

  • Fixed a deadlock that could occur when closing a stream.
  • Made looping MP3 streams loop a little cleaner.
  • Fixed a deadlock that could occur when starting a 3D sample from the background timer thread.
  • Added AIL_close_input call to voice chat client example program.
  • Fixed an obscure bug in the RIB provider enumeration functions.
  • Fixed a problem when setting the orientation of a H3DSAMPLE before calling AIL_set_3D_sample_file.

Changes from version 6.0a to 6.0b (01-15-2000)

  • Made the Exam3D example always reset the effects level to 1.0F after a switch. Fixes not being able to hear reverb on some EAX drivers.
  • Changed the Miles voice chat examples to use a less commonly used port number to lessen the chance of possible conflicts.
  • Fixed the Miles Sound Studio occasionally using the voice chat encoder instead of the MP3 encoder.
  • Switched to a new threading model that should be more robust with poor sound card drivers and other libraries that use DirectSound concurrently with Miles (you shouldn't have to call AIL_lock anymore). The new threading model can be turned on and off with the new AIL_MUTEX_PROTECTION preference (default is on).
  • Fixed a few harmless BoundChecker warnings.
  • Should be fewer skips in the 2D system when switching 3D providers (this is probably as good as we can make this with the Windows 9x's crummy thread scheduler).
  • Switched the filters to be compiled with the VC 6 switch "/QIfist" to allow fast floating point to integer conversion, while still giving the compiler good scheduling opportunities.
  • Updated the Lagrangian Interpolating filter to the correct source file.
  • Added the new AIL_register_3D_EOS_callback function that allows you to set an end-of-sample callback for 3D samples (added on all 3D providers).
  • Switched to using the SetEQ function to model occlusions with a hardware low-pass filter on A3D 2 cards (sounds as good as EAX).
  • Somewhat simplified the threading model in the A3D 2 and QSound providers (should be a little quicker when starting or stopping sounds).
  • Simplified the threading model in the RSX provider drastically (should respond more quickly).
  • Fixed a crash if you changed an A3D 2, EAX 2, or Miles fast 2D settings before calling AIL_set_3D_sample_file.
  • Fixed a problem with the Fast 2D provider where the low-pass filter could be dropped when replaying the same sound.
  • Automatically invert minimum and maximum distances if they are passed in backwards.
  • Fixed the 2D streaming system to handle corrupt or unsupported MP3 files without crashing.
  • Fixed the 2D streaming system to automatically close all playing streams when calling AIL_waveOutClose or AIL_shutdown (avoids a shutdown crashes).
  • Fixed a nasty crash bug when re-using 2D samples or 3D samples in the Fast 2D provider where an applied DSP filter could go uninitialized.

Changes from version 5.0r to 6.0a (10-18-2000)

  • Switched to a new directory structure to better handle the upcoming multi- platform support (see ReadMe.Txt for details).
  • Added new voice chat codecs and an new client-server system to show it off (MSSChat.EXE). Since Miles doesn't supply a network layer, our example uses TCP for its transport. Games should add the voice packets into their existing network layers for best results.
  • Added a new input API for recording digital audio.
  • Added new set of 18 DSP-style digital audio filters. Low-pass, high-pass, equalizers, reverb, EAX emulation with occlusion and more!
  • Changed the AIL_set_3D_sample_distances function to only take one set of minimum and maximum parameters (none of the providers except RSX supported different front and back distances). You'll have to make a change to your code to handle for this change.
  • Added new 3D functions to set the room type, speaker type, sample effects level, sample obstruction, sample occlusion, and conical emission for samples (see the new Exam3D.exe for examples of all of these functions).
  • Added three new DirectSound 7 only 3D providers - full HRTF, light HRTF, and pan and volume only. You must have DX7 installed to use these providers.
  • Added a new EAX2 provider with hardware support for occlusions and obstructions. All of the advanced settings are available as provider and sample level attributes and preferences.
  • The Miles Fast 2D and Dolby providers now offer software emulation of the EAX room styles. These providers also use a low-pass filter to support occlusions. Use this functionality with care - each voice with EAX effects costs 7% of the CPU on a P5/200.
  • Added a new function to set the directory that contains all of the Miles redistributable files (ASIs, M3Ds, FLTs, etc). Just call AIL_set_redist_directory *before* AIL_startup to tell Miles where to find its files.
  • Upgraded all of the existing 3D providers to support occlusions and obstructions by simulating them by adjusting the sample volume.
  • Added a new A3D2 provider - you can request the A3D2 interface and download geometry or use our new EAX reverb emulation (we create geometry on the fly that matches the EAX room styles as closely as possible).
  • Added a new QMixer provider (which cannot be redistributed without a license from QSound - give Mitch a call for details). This provider creates a nice, sweet 3D sound - definitely worth checking out.
  • Added sub-block looping of streamed files.
  • Added normal doppler effects to RSX (not based on changing positions, but rather by the 3D velocity function).
  • Removed support for the Microsoft mixer in our DirectSound support (since there wasn't any reason to use theirs any more). This means that the DIG_USE_MSS_MIXER preference is gone now.
  • Made the DOS examples compile under Win32 or DOS - now stored in a CONSOLE directory.
  • Made the Miles Sound Studio resizable under Win 98 and Win NT.
  • Fixed burst of static when running under DX7 with the debug libraries.
  • Pre-normalize the 3D orientation before passing it into M3D providers.
  • Fixed tons of other small bugs.

Changes from version 5.0q to 5.0r (09-22-1999)

  • Fixed a rare deadlock crash when using multiple DirectSound buffers (like when using Smacker and Miles together or when using the 3D DirectSound hardware provider with 2D sounds).
  • Fixed a memory fragmentation problem under DOS.
  • Allow more 3D voices on Aureal cards.

Changes from version 5.0p to 5.0q (09-06-1999)

  • Improved DirectSound buffering to help skipping under heavy loads and crummy DirectSound drivers. Added a new preference that allows you to control how far in advance to mix ahead. Use DIG_DS_MIX_FRAGMENT_CNT to control how many fragments to mix ahead (defaults to eight 8 ms fragments).
  • Improved the panning routines in the Fast 2D 3D provider - should pan from side to side much more smoothly now.
  • Fixed a rare waveOut deadlock problem.
  • Worked around some A3D stability problems.
  • Added a new function to determine the slowest timer response since Miles was started. Just call AIL_get_timer_highest_delay to get the worst time (0 means the system is running perfectly). The mixing system will start to skip when this number exceeds 64 ms. If this happens in your application, you can use the new preference DIG_DS_MIX_FRAGMENT_CNT to increase the mix ahead time (at the expense of latency).
  • Fixed the EAX constant for flipping back to automatic sample reverb control.
  • Fixed MMX support (goofy bug).
  • Fixed callback on preloaded HSTREAMs.
  • Changed the type of H3DSAMPLEs to be not defined to an (void*) pointer to enable better compile time type checking.
  • Fixed a bug when a NULL was passed to the red book routines.
  • Cleaned up the Delphi interface files somewhat.
  • Fixed AIL_allocate_file_sample to accept an MP3 file.
  • Made all of the ADPCM routines fail on non-4 bit IMA ADPCM compressed data.
  • Fixed the floating point status not being saved in a DOS timer callback.
  • Made the RSX provider consider only the minimum distance (not scaled by the maximum) for volume attenuation.
  • Turned on doppler pitch shifting under RSX.
  • Fixed a bug in the XMIDI sequencer where channel mutes weren't being handled properly with callback prefix functions (whew).

Changes from version 5.0n to 5.0p (04-25-1999)

  • Made the MP3 parser more tolerant of files with bogus pre-header data.
  • Added compatibility with variable bit-rate MP3 files to the MP3 decoder.

Changes from version 5.0m to 5.0n (04-20-1999)

  • Fixed the RSX provider dropping voices when playing multiple samples through a H3DSAMPLE in close succession.

Changes from version 5.0k to 5.0m (04-09-1999)

  • Added a new optimized assembly MP3 math module for Intel and AMD 3DNow - up to 10% better on Intel, 54% better on AMD! Miles is now by far the fastest MP3 decoder on AMD machines.
  • Fixed a granularity problem when seeking in a non-compressed stream using AIL_set_stream_ms_position.
  • Fixed a crash if you called AIL_shutdown when 3D samples were still playing.
  • Fixed an RSX startup crash when running under the MSVC debugger under NT.
  • Allocated service threads for 3D samples at sample-allocation time vs. provider-open time.

Changes from version 5.0i to 5.0k (03-31-1994)

  • Made the "Maximum supported samples" provider attribute also a *preference* in the Fast2D, Dolby Surround, and RSX providers. This means you can set the number of available 3D samples in these three providers by calling the AIL_set_3D_provider_preference function *before* you call the AIL_open_provider function. For the Fast2D and Dolby provider, you need to also insure that their are enough 2D HSAMPLEs available for the number of 3D H3DSAMPLEs that you request (use the DIG_MIXER_CHANNELS Miles preference to set the number of 2D HSAMPLEs).
  • Made AIL_set_3D_sample_distances and AIL_3D_sample_distances take F32-typed parameters rather than U32.

Changes from version 5.0h to 5.0i (03-06-1999)

  • Fixed a bug in the DLS software synth that would crash if you looped a single MIDI file for more than 71 minutes.

Changes from version 5.0g to 5.0h (02-25-1999)

  • Fixed a crash bug when closing the RSX 3D audio provider if legacy RSX had never been previously installed.
  • Fixed a new parameter names to avoid collisions with the STL.

Changes from version 5.0f to 5.0g (02-15-1999)

  • Changed the calling convention of the RIB-based providers slightly (M3Ds, ASIs, and FLTs). Make sure you update *all* of your MSS files - not just MSS32.DLL!
  • Added the new Dolby Surround M3D provider. This is a Dolby-certified run-time 3D positioner. It allows multi-speaker systems like those from Cambridge Soundworks, Boston Acoustics, and Altec Lansing to play sounds audio from the rear speakers - "true" 3D sound positioning.
  • Added a new filter called "CAPTURE.FLT". This filter writes all Miles digital audio output to a specified wave file. This lets you create complete sound tracks for your running applications! You simply set the filename and then load the filter to begin recording your application's output.
  • Further support has been added to the standard HSAMPLE-based API for installable digital audio processor modules, or "filters." Filters allow the manipulation of sample data in real time, just before it is mixed into the driver's output buffer. Several new API functions have been added to make it easy for applications to select, install, configure, and use filters.
  • The use of these new functions is demonstrated in the FILTER.CPP console application in the FLT directory, along with a simple example filter provider which emulates MSS's reverb support in an externally-installable module.
  • To associate a filter provider with a given HSAMPLE, simply call the existing AIL_set_sample_processor function with DP_FILTER as the SAMPLESTAGE parameter. It is not necessary to explicitly open the filter with AIL_open_filter first; however, be advised that some filters may need to allocate large amounts of memory or perform CPU-intensive setup processing when first opened. Calling AIL_open_filter at application startup time may help avoid perceptible delays when a given filter is associated with an HSAMPLE for the first time.
  • Open filters are cleaned up automatically at driver shutdown time. Even if AIL_open_filter is called explicitly by the application, it is not necessary to call AIL_close_filter unless the application needs to free up resources consumed by a filter which it no longer intends to use. Keep in mind that each installed filter may add a small amount of CPU-usage overhead to the MSS digital audio pipeline, even if no HSAMPLEs are using the filter.
  • Filter support is available only in the Win32 MSS API, and only if the DIG_USE_WAVEOUT or DIG_USE_MSS_MIXER preferences are enabled.
  • Added the DIG_F_USING_ASI flag in AIL_stream_info flags return parameter.
  • Increased the number of voices available with RSX to 16.

Changes from version 5.0e to 5.0f (01-31-1999)

  • Added the new integrated RSX provider (RAD acquired RSX in January 1999). You can now use the RSX provider without installing RSX first! There were many improvements made to improve quality and compatibility. Be sure to try this new provider - it is now one of the best 3D options!
  • Fixed a bug in the Fast 2D M3D provider where the default volume level could be set incorrectly.
  • Dropped the volume by 3 db when the sound is behind you in the Fast 2D M3D provider.
  • Improved the speed of stopping 3D samples in the DirectSound3D derived 3D providers.

Changes from version 5.0d to 5.0e (01-01-1999)

  • Fixed a bug when opening a normal wave file with the streaming API (introduced by the support for wave-wrapped MP3 files).

Changes from version 5.0c to 5.0d (12-20-1998)

  • Add a 3D provider that uses the Miles 2D interface (pitch/pan/volume) for extremely fast simulated 3D audio.
  • Fixed a lock-up bug in the MP3 parser where certain non-MP3 data blocks could cause a crash.
  • Reduced the speaker static when loading and unloading 3D providers.
  • Added support for wave wrapped MP3 files in the high-level API (both file name and file handle based).
  • Fixed a bug where the end of 3D digital sample could be clipped off.
  • Fixed a bug when selecting a non-A3D provider after the A3D provider.
  • Forced RSX not to use MMX (which was the cause of the awful clipping noise).

Changes from version 5.0b to 5.0c (11-15-1998)

  • Added software reverb to the digital API. You can now set reverb parameters on any sample, stream, quick handle, or soft-synth MIDI sequence. The new functions allow you to set the reverb level (amount of reverb), reverb decay time, and reverb reflection time. See the Miles Sound Player for an example of the reverb parameters.
  • Fixed a few problems in the Delphi interface.
  • Added SBLive info in the driver list (uses the SB16 driver).
  • Fixed a bug in the file-based MP3 decompressor where the channels and bits were inverted in the output wave header.
  • Added hardware DLS support for the Aureal Vortex chipset (both Vortex 1 and Vortex 2). Also added hardware DLS selections to the Miles Sound Player.
  • Fixed some thread synchronization problems in the 3D providers.
  • Added a DOS without MPEG library.

Changes from version 5.0a to 5.0b (10-19-1998)

  • This is a maintenance release. The .M3D 3D hardware providers have changed, so be sure to update any copies you currently keep in your application directory.
  • Added AIL_set_3D_sample_info, to allow direct specification of a block of raw sample data via an AILSOUNDINFO structure.
  • Added AIL_set_3D_sample_playback_rate and AIL_3D_sample_playback_rate functions to allow on-the-fly control of a 3D sample's playback rate.
  • Added three functions for per-sample attribute control in the 3D sound API. AIL_enumerate_sample_attributes, AIL_3D_sample_attribute, and AIL_set_3D_sample_preference allow per-sample attributes to be listed, read, and written, respectively.
  • Some 3D providers (notably Creative EAX at this time) allow control of parameters such as effect intensity on a per-voice basis. On the Creative EAX provider (MSSEAX.M3D), the new per-sample attribute functions will expose "EAX sample reverb mix", which can be read with the AIL_3D_sample_attribute function or written with the AIL_set_3D_sample_preference function.
  • Most applications should not need to set the "EAX sample reverb mix" preference. If an EAX application creates a sample and does not set this property, EAX automatically calculates the reverb mix for the sound source based on its volume and distance. If an application does want to override EAX's control of this attribute, its value may be varied over the range of 0.0 (no reverb at all added to the source) to 1.0 (the maximum amount of reverb added to the source). If you want to put the reverb mix attribute back under the control of EAX, you can set the value using the constant EAX_REVERBMIX_USEDISTANCE, defined in EAX.H as -1.0F.
  • Fixed a bug which could potentially cause deadlocks when setting or retrieving EAX environment properties.
  • Fixed a truncation problem in the AIL_find_DLS function.
  • Fixed a bug in the end of stream callback.
  • Updated the Delphi interface files to 5.0.

Changes from version 4.0g to 5.0a (10-04-1998)

  • Major new version - almost everything changed somewhat. Highlights:
  • All new digital mixer (actually the digital mixer from our DLS synthesizer) - it is much faster, has MMX support, supports on-the-fly filtering, and can call pre- and post- mix sound processors.
  • MSS now uses the new Miles mixer even when running under DirectSound - if you start and stop many sound samples, then this can increase your performance dramatically.
  • New API for adding runtime bound APIs to MSS (called RIB).
  • New API for adding audio codecs to MSS called "ASI" (which is built with RIB).
  • New API for adding 3D audio providers to MSS called "M3D" (which is also built on RIB).
  • New MPEG Layer-3 ASI-based decoder (note that you must sign a license addendum to obtain the decoder). MP3 is integrated completely into MSS - you don't even have to decompress the MP3 data first (although you can for performance reasons). MSS does NOT support MPEG Layer 1 or MPEG Layer 2 files, btw.
  • New high-level 3D API - with the MSS 3D API, you can support any of the Miles M3D audio providers (DirectSound software, DirectSound hardware, Aureal's A3D, Creative's EAX, and Intel's RSX - more coming soon). Note that Intel is currently working on several bugs in RSX, so the RSX provider is noisier than it will be.
  • New API for high-level access to the Miles mixer. This means you can do format conversions and pre-mixing in your application (without actually playing the sound).
  • New functions for compressing and decompressing with an ASI codec. Note that Miles does NOT supply a redistributable MPEG Layer 3 *encoder*. You can purchase a encoder for use with the Miles Sound Studio for $95, but it is still not redistributable.
  • The DLS synthesizer is now capable of using MP3 compression for the instrument data. This makes MSS MIDI files even smaller! You must purchase the Miles MPEG Layer 3 encoder to create these files, however.
  • Added a callback to most of the File Format services functions that is called periodically during lengthy operations (for status displays).
  • New function to write out a wave file from just a memory pointer and format description.
  • Improved autodetection of application master HWND.
  • New function to retrieve the HWND that the MSS system is using (for DirectSound and 3D library support).
  • Fixed the default pan setting for drum voices in the DLS synthesizer.
  • Stream callbacks are now made when the sound completes (rather than when all of the audio has been read from the file).

Changes from version 4.0f to 4.0g (06-11-1998)

  • Fixed a bug when looping ADPCM sound streams.
  • Fixed some Win32s problems.
  • Fixed a bug where end of stream callbacks would only be made once.

Changes from version 4.0e to 4.0f (06-03-1998)

  • Fixed use of greater than 1MB DLS files under Windows 3.x.

Changes from version 4.0d to 4.0e (05-10-1998)

  • Fixed an obscure buffer boundary bug in the ADPCM decompressor.

Changes from version 4.0c to 4.0d (03-30-1998)

  • First release of the DOS version of MSS 4.
  • Fixed the stream millisecond positioning functions.
  • Merged a lot of the Windows and DOS source code.
  • Shipped the newest S3BASE.DLL in the WinTools directory (adds from memory loading for SonicVibes cards).
  • New DOS driver for the ESS AudioDrive (runs better under a Win95 DOS box).
  • Added DOS driver for the Maxi Sound 64 sound card.
  • Updated Delphi interface files to version 4.0.
  • Fixed a bug in the DLS synthesizer with some of the weirder DLS instruments.

Changes from version 4.0b to 4.0c (03-20-1998)

  • Doubled the speed of ADPCM decompression.
  • Fixed ADPCM mono samples playing without volume control.
  • First release of the Win16 version of MSS 4.
  • Dumped the use of the Shrinker DLL compressor - all kinds of loading problems.
  • Fixed a few compiler warnings in MSS.H.

Changes from version 4.0a to 4.0b (03-09-1998)

  • MSS now uses a single header file for all platforms: MSS.H
  • First release of the Win32 SDK.
  • Miles Sound Studio: easy-to-use utility for manipulating MIDI, XMIDI, DLS, and digital sound files.
  • New native Win32 version of MIDI Echo.
  • New Tools API - convert MIDIs to XMIDIs, compress/decompress ADPCM files, DLS file handling functions, etc. The Miles Sound Studio was written with these functions.

Changes from version 3.6f to 4.0a (02-24-1998)

  • DLS support: high and low-level APIs, a bunch of new utilities, MMX and non-MMX support.
  • ADPCM compression support: on-the-fly compression in the sound mixer, file compression and decompression APIs, and support for DLS sample compression.
  • Miles Sound Player - new application to play MIDI/XMIDI (with and without DLS installed), and digital sound files.
  • New time-based positioning functions for both sequences and samples (current position, total length, and seek).
  • Quick API additions: DLS support, time position, normal MIDI file support.

Changes from version 3.6e to 3.6f (11-07-1997)

  • Changed the Quick API to attempt to load the MIDI driver after the digital driver (instead of before) to work around Creative Labs MIDI drivers that attempt to allocate the digital driver for software music synthesis.
  • Made quite a few low-level changes to the MIDI sub-system for the DLS support coming in version 4.0.
  • Decreased the delay in the MIDI traffic when ending a MIDI sequence.
  • Fixed an open bug in the MSS Xtra.

Changes from version 3.6d to 3.6e (10-20-1997)

  • Now use the DSBCAPS_GETCURRENTPOSITION2 flag to work a little better with emulated DirectSound drivers.
  • Added a function called AIL_set_DirectSound_HWND that will allow you to explicitly set the HWND of your application. Call this function after AIL_waveOutOpen.
  • Fixed a few bugs in the Miles Xtra with opening digital audio cast members.
  • Fixed a bug in the Miles Xtra in the positioning command for streaming audio.
  • Fixed a crash when there was no event callback installed and an AIL_send_channel_voice_message call was issued with no sequence handle specified.

Changes from version 3.6c to 3.6d (08-25-1997)

  • Fixed a bug in AIL_minimum_sample_buffer_size that causes stuttering in the streaming API under DirectSound when the sound format didn't match the DirectSound output format.

Changes from version 3.6b to 3.6c (06-08-1997)

  • Fixed bug in the streaming API under Win32 where some wave files wouldn't open.

Changes from version 3.6a to 3.6b (03-07-1997)

  • Fixed bug in waveOut mixing code that could cause all sounds to stop under very high sound loads.
  • Fixed bug in red book volume control for CD devices that allowed stereo volume resolution.
  • Fixed some debug stuff that was left in the Quick example application.
  • Switched the newest Causeway (which works around a bug in the Ensoniq VIVO drivers).
  • Fixed a bug if you called AIL_start_sample or AIL_load_sample_buffer from an EOB or SOB callback (EOS and timer callbacks were fine).
  • MSS doesn't look for the application hwnd in AIL_digital_handle_reacquire again - it just uses the old one.

Changes from version 3.5f to 3.6a (01-25-1997)

  • Added a new high-level streaming API - stream disk files in 4 calls! Streams work just like samples - you can change the playback rate, volume, pan, loop count, etc.
  • Updated the timer system to work around the dreaded Microsoft VC debugger problem under Windows 95 and Windows NT (slowdowns and crashes when sitting on a breakpoint for a long time).
  • Added volume control functions for redbook audio (AIL_redbook_volume and AIL_redbook_set_volume). Uses MSCDEX for DOS, the mixer API for Win32, and the aux device calls for Win16.
  • Fixed a bug in the DOS redbook control functions that would sometimes cause a redbook track not to play (good catch - BullFrog!)
  • Integrated the Fatman's General MIDI FM patches directly into the library.
  • Added a new function to duplicate an existing quick handle (AIL_quick_copy). This function doesn't duplicate the audio memory - only the handle info.
  • Added two new functions to control the speed and volume of a quick handle (AIL_quick_set_speed and AIL_quick_set_volume).
  • Added a new function to return the digital and MIDI driver handles when you used the Quick API to init the system (AIL_quick_handles). This is handy because you can now use AIL_quick_startup to simplify initializing MSS, and still use the full API for everything else.
  • Fixed a bug in AIL_strnicmp that was causing a crash when loading data out of a 32-bit resource DLL file.
  • The MSS DLLs now check to see if they have been incorrectly installed in Windows or Windows system directory.
  • Added the AIL_get_preference function to the DOS API.
  • Took out the virtual memory feature of VTOR - use the Smacker utilities to convert huge wave files to RAWs.
  • Fixed a bug in AIL_file_read when an pointer was passed and the read failed.
  • Fixed a bug in AIL_file_write that would free the pointer if the write failed.
  • Fixed a bug in the quick API where the MIDI system occasionally fail to load under NT.
  • Various minor clean-ups in the Delphi interface units.

Changes from version 3.5e to 3.5f (10-22-1996)

  • Adjusted the method that the 16-bit DLL locks its memory for extreme low memory machines (Win3.x and Win32s).
  • Fixed potential crash when completely out of DOS memory in the 16-bit DLL (Win3.x and Win32s).
  • Preceded the system functions with "AIL_" to fix function name collisions with VFX from Miles Design. The old function names are still defined to match the new names, so no source should have to be changed.
  • Because of these function name changes and because Smacker dynamically links to MSS, you must update to at least Smacker version 2.2B for MSS 3.50F.

Changes from version 3.5d to 3.5e (08-18-1996)

  • Fixed bug in release/reacquire code for DirectSound.
  • Added new ESS drivers - now run under Win95 DOS box.

Changes from version 3.5c to 3.5d (09-14-1996)

  • Fixed unusual problem of DirectSound dropping samples when many samples are played at once.
  • Improved method that the background task uses for CPU-sharing, so that it is slightly faster.
  • Fixed bug in MIDI driver loading code - seen with Gravis driver & MidiForm.

Changes from version 3.5b to 3.5c (08-22-1996)

  • Added locking calls for volume and pan setting in the DirectSound code.
  • Added AIL_digital_handle_release and AIL_digital_handle_reacquire for focus control under Windows.
  • Added AIL_MIDI_handle_release and AIL_MIDI_handle_reacquire for focus control under Windows.
  • Added SMP_PLAYINGBUTRELEASED and SEQ_PLAYINGBUTRELEASED flags for HSAMPLE and HSEQUENCE status flags.
  • Added new macro, "AIL_DLL_version", to return the current DLL version (doesn't actually call into the DLL, so it is always safe).
  • Fixed weirdness with the background task complaining about Bad Code Pointers.
  • Changed the way AIL_redbook_status works to speed it up.
  • Added AIL_serve calls in the redbook API to avoid stutters on slow CDs.
  • Changed standard types (S8, U8, etc) slightly (to defines)
  • Under DirectSound, you can now pass NULL for the lpFormat parameter - this tells MSS not to adjust the primary sound buffer.

Changes from version 3.5a to 3.5b (07-07-1996)

  • DOS version now has all of the features of the Windows version (red book support, quick-integration API, sub-block looping, etc).
  • Fixed error in linked list code of the quick API for Windows.
  • Fixed error in AIL_send_channel_voice_message when the driver handle is NULL.
  • Changed AIL_ms_count to call QueryPerformanceCounter under NT.
  • AIL_ms_count under DOS inside a Windows DOS box can read the Windows timer for millisecond accuracy.
  • Added "FILE_READ_WITH_SIZE" flag to FILE_READ function, so that it can return the size of the data read as the first four bytes of the returned pointer.
  • AIL.LIB can be used for register or stack based programs (there is no need to recompile for stack based programs anymore).
  • MSS can now be used with Watcom 9.5 to 10.6. RAD recommends version 10.6.
  • Added new AIL_set_driver_directory function to load drivers, .INI files, and patch files from alternate directory (MSS still always searches the current directory first).
  • You must now call AIL_startup before any other MSS calls (including FILE_read, MEM_alloc, etc).
  • Callbacks are now typed and must use the AILCALLBACK calling convention.
  • Added two new redbook functions. AIL_redbook_track returns the current playing track number. AIL_redbook_retract closes the CD drive door.
  • Timer callbacks now synchronize the callback frequency to AIL_ms_count. This improves MIDI playback drastically under DOS inside a Windows DOS box. It also prevents long-term timer counting drift if you use MSS timer to track time (use AIL_ms_count directly for best accuracy).
  • DDK has been integrated into the SDK for convenience.
  • All example programs and tools have been bound with the Causeway DOS extender.
  • Added new DOS drivers for the AMD Interwave and the NVidia multimedia card.
  • The VBL flag no longer used for delaying (in either the library or the drivers).
  • SetSound can display the current Windows 95 configuration when running in a Windows 95 DOS box.
  • Built-in Borland C support for both Windows and DOS PowerPack.
  • SoundFont support now supplied directly with MSS.
  • AILEXPORT has been renamed to AILCALLBACK for consistency with DOS.
  • Renamed main libraries and header to use MSS instead of AIL.
  • VTOR uses virtual memory so that large .WAVs or .VOCs can be converted. Under Windows and Windows 95 DOS boxes, virtual memory is limited to 16 MB, so you may have to run VTOR under normal DOS to convert really huge files.
  • Added 16- and 32-bit Delphi interface units.

Changes from version 3.04a to 3.5a (04-11-1996)

  • Add complete built-in DirectSound support. There are several new DirectSound specific functions - see the docs for details.
  • AIL_startup can be called multiple times - but calling AIL_shutdown closes everything down immediately. This allows you to call AIL_startup several times in your application, and call AIL_shutdown once in your closing procedure.
  • Fixed a harmless thread handle leak.
  • Also fixed is AIL_minimum_sample_buffer_size which was under-reporting by a factor of 4.
  • Added the new Quick Integration API. See the docs for details.
  • Added new AIL_digital_configuration call that returns info about the current sound driver.
  • Added new sub-block looping feature - can loop internal pieces of a buffer. Use the AIL_set_sample_loop_block function to set the loop points.
  • Callbacks now work under Win32s - but are not called at interrupt time. Rather, they are distributed from the Windows messaging system, so you must yield to Windows to receive callbacks
  • Added new Red-Book audio interfaces - play CD audio tracks quickly and easily.
  • Multiple 16-bit and Win32s apps can be loaded at the same time.
  • Fixed crashes when running 16-bit DLL with other 32-bit apps or libraries.
  • Fixed crashes when memory would move.
  • Added new millisecond count call - AIL_ms_count. Allows accurate timing without having to create absurdly fast timers.
  • Added new starvation call - AIL_sample_buffer_info for video players.
  • AIL_serve is no longer needed in your message loop. Under Win32, a background thread handles servicing. Under Win16 and Win32s, a background task takes care of it.
  • MSS now works under Windows NT - (the NT MIDI drivers are still pretty buggy however).

Changes from version 3.03d to 3.04a (02-04-1996)

  • Integrated Win32s support directly into WAIL32.DLL. This means you can create one executable that supports Win 95, Win NT, and Win32s. To support Win32s, you must distribute both WAIL32.DLL and WAIL16.DLL.
  • You must use MEM_alloc_lock for memory that you intend to use for sample or sequence data (with AIL_set_sample_address, AIL_load_sample_buffer, AIL_init_sequence, etc). MEM_alloc_lock returns 32-bit pointers that have been locked and fixed for Win32s. Under Win 95 or Win NT, MEM_alloc_lock just returns GlobalAlloc-ed memory, so you can use this function for all environments. If you pass in a pointer that isn't created with MEM_alloc_lock, MSS will display a error message box.
  • HDIGDRIVER, HSAMPLE, HSEQUENCE, etc, are all handles under Win32s - they are not pointers, so you can't dereference them.
  • Internal MSS calls are not captured in the debug trace file when running under Win32s.
  • Callbacks aren't supported yet.
  • Fixes segment wrap around in WAIL16 on sound cards that need large Windows buffers (>64K).
  • Marks several variables as volatile, so that WAIL can be compiled with optimizations on.
  • Pointers are checked for validity as they are freed.

Changes from version 3.03c to 3.03d (11-22-1995)

  • Switched to a new thread synchronization technique which should fix deadlocking problems previously encountered by some 32-bit MSS applications.
  • Previous versions of the 32-bit MSS library could crash if an attempt was made to start more than one instance of a MSS application. This has been fixed.
  • AIL_branch_index could fail to work properly in previous versions of MSS. This problem has been fixed for this release.

Changes from version 3.03b to 3.03c (11-07-1995)

  • SETSOUND now includes explicit support for the new Yamaha DB50-XG WaveForce(TM) daughterboard via the MPU401.MDI driver.
  • MSS for Win32 now uses thread synchronization.
  • If all playing samples had their volume set to 127, it was possible for the AIL_set_digital_master_volume command to fail to control the overall digital output level. This has been fixed.
  • The SETSOUND installation program did not uninstall drivers after successful detection. This caused no reported problems; however, the message "Out of timer handles" could appear if the user were to select and install any driver more than 16 times. SETSOUND now uninstalls drivers after detection to avoid the possibility of this error message.
  • The AIL_MDI_driver_type function caused premature termination of debug scripts when the AIL_DEBUG feature was in use. This has been fixed.
  • Memory past the end of XMIDI files could be accessed by AIL_init_sequence, in cases where XMIDI files smaller than 1024 bytes were played. This caused occasional page faults in the Windows MSS system, but no problems were ever reported in the DOS MSS system. This bug has been fixed, however, in both versions of MSS.
  • At the end of an unlooped XMIDI sequence, the sequence loop count is now reset to 1. This allows a sequence to be restarted without undesirable looping.
  • Under certain rare circumstances, unwanted pauses occurred during XMIDI playback when using the FOR/NEXT XMIDI controllers or the AIL_branch_index function. These pauses have been eliminated in this release.
  • The AIL_end_sequence function previously called the end-of-sequence (EOS) callback function, even if the sequence was already done. This behavior has been corrected.
  • The Microsoft Windows Sound System driver (SNDSYS.DIG) has been patched to fix a bug that caused a detection problem on some systems, particularly Compaq machines.
  • The standard Sound Blaster digital driver (SBLASTER.DIG) could cause lockups or "Transfer Stack Overflow" messages during detection when running under Windows 95. This was due to the use of an extremely short DMA buffer to check for auto-init DMA capabilities. In this release, the DMA verification buffer in SBLASTER.DIG has been increased in size to avoid problems. No other drivers, including those for the Sound Blaster Pro and Sound Blaster 16, were affected by this problem.

Changes from version 3.03a to 3.03b (06-29-1995)

  • Changing the digital master volume level had no effect on samples whose volume level was set to 127. This has been fixed.
  • A VMM page-locking problem with the FlashTek DOS extender version of MSS has been fixed.

Changes from version 3.03 to 3.03a (06-25-1995)

  • Sporadic crashes at shutdown time may occur in earlier MSS releases if a sequence handle is allocated with AIL_allocate_sequence_handle but never actually initialized with AIL_init_sequence. This patch corrects this problem, which affected only the MS-DOS versions of MSS.

Changes from version 3.02 to 3.03 (06-18-1995)

  • Two new drivers, SNDSYS.DIG and ESFM.MDI, provide support for the Microsoft Windows Sound System and ESS Technology ES1688, ES1788, and ES1888 chipsets, respectively. The SETSOUND program recognizes these new drivers by means of an updated AILDRVR.LST file.
  • Support for the Borland Power Pack and Zortech/Symantec compiler packages is now available. Please note that by default, the MSS system is built for the more popular Watcom/Rational package. To use MSS with any other compiler/DOS extender package, it is necessary to delete all .OBJ, .LIB, and .EXE files and recompile the desired library version. The .MDI and .DIG drivers, as well as the files in the TOOLS subdirectory, do not need to be rebuilt.
  • Four new functions provide a "master volume" control for all digital samples and XMIDI sequences: AIL_set_digital_master_volume, AIL_set_XMIDI_master_volume, AIL_digital_master_volume, and AIL_XMIDI_master_volume
  • Please note that like the AIL_set_sequence_volume function, AIL_set_XMIDI_master_volume will not have the desired effect on sequences which do not include MIDI Part Volume controllers (7) at the beginning of each track. Refer to the updated documentation for further information on these functions.
  • The function AIL_register_beat_callback has been added to allow applications to request callback service at sequence beat transition points. Refer to the description of this function AND the AIL_sequence_position function in the documentation before attempting to use either function!
  • The function AIL_MDI_driver_type has been added to help applications identify the synthesis technology provided by various MSS drivers. This function may be used to select different XMIDI sequences for various sound synthesis platforms. Refer to the documentation for details.
  • A new XMIDI controller has been implemented. The XMIDI Channel Mute controller (107) can be used to selectively mute channels in sequences. Refer to the updated documentation for information on the XMIDI Channel Mute controller.
  • The prototypes of the AIL_install_DIG_INI and AIL_install_MDI_INI functions have been changed to provide enhanced error-reporting capabilities. It is now possible to distinguish between failure due to a missing .INI file and failure due to driver initialization or hardware detection problems. Refer to the updated documentation file for details.
  • Previous versions of MSS truncated 16-bit sample data to 8-bit sample data when panpot or volume scaling was used (panpot != 64 or volume < 127). With this release, 16-bit sample data is scaled with a multiply/shift sequence that preserves full 16-bit sample precision.
  • For consistency with the new Windows MSS package, the DIG_DRIVER * and MDI_DRIVER * data types have been replaced with the HDIGDRIVER and HMDIDRIVER handle types, respectively. The old pointer types may still be used, but new applications should be written with the new handle types for compatibility with the Windows MSS API.
  • Previous versions of MSS shut down interrupts during the digital mixing process, which caused problems with high-speed serial communications. By default, MSS V3.03 no longer disables interrupts at any time during digital audio processing. A new preference name, DIG_SS_LOCK, has been added to allow applications to restore the former behavior of shutting down interrupts while updating the DMA buffer. Few applications should need to change the DIG_SS_LOCK preference value.
  • When playing a stereo digital audio sample on a monaural sound card, previous versions of MSS truncated the right channel source data and played only the left channel data. MSS V3.03 allows the AIL_set_sample_pan function to fade linearly between the left and right source channel in this situation.
  • In previous versions of MSS, it was possible under exceptionally rare conditions for a nested INT 8 interrupt to cause crashes due to stack corruption. Under Windows 95, however, the probability of protection faults and crashes is greatly increased. This bug has been fixed for this release of MSS; additionally, Windows 95 itself has been patched to correct the bug in legacy applications by automatically modifying the faulty instructions in the MSS INT 8 ISR. Customers with the retail release of Windows 95 should not be affected; however, early beta versions (pre-490) can exhibit problems.
  • A minor bug in the digital mixer code caused clipping tests to be performed even with only one actively-playing sample. This bug has been fixed for this release, resulting in faster digital audio performance.
  • The AIL_resume_sample function could fail to operate properly if no other samples were playing at the time it was called. This has been fixed.
  • Reports have been received of lockups with Sound Blaster 16 daughterboards (such as those from Roland and Creative Labs) which occasionally occur during extremely intense bursts of MIDI traffic while digital audio is in use. The MSS MPU401 driver has been patched to provide a partial workaround for this problem; however, momentary digital audio glitches may still be noted during fast volume fades and other periods of high MIDI activity. Because this problem is due to a hardware bug in the Creative chipset, no completely reliable software workaround is currently known. However, difficulties arising from the bug are quite rare and should not be a cause for concern with most applications.
  • AIL_start_sequence formerly reset the sequence loop count (if any) to 1, effectively disabling any loop count previously established by AIL_set_sequence_loop_count. This has been fixed in version 3.03 -- AIL_set_sequence_loop_count may now be called either before or after playback begins.

Changes from version 3.01 to 3.02 (01-18-1995)

  • The DRIVERS directory now contains a complete MSS driver configuration program (SETSOUND.EXE) which may be included in your application. SETSOUND must be executed before any of the MSS example programs in the DRIVERS directory can be run. Consequently, the example programs no longer require driver filenames to be specified directly on their command lines.
  • SETSOUND is very easy to use and can shave days or weeks of programming time from an application's development cycle. However, you should refer to SETSOUND's complete description in the Tools Reference section of the manual to help you get the most out of this powerful new utility.
  • The contents of the old MIDI and DIGITAL directories have been merged into the outer DRIVERS directory. Minor revisions have been made to the example programs and makefiles to accommodate this change.
  • SBLASTER.MDI, SBPRO1.MDI, and SBPRO2.MDI now check the BLASTER environment variable to permit FM sound autodetection at addresses other than 220h. Previously, only the Sound Blaster-series .DIG drivers checked the BLASTER variable.
  • DMA channel 0 is now available for use with Sound Blaster Pro adapters. In earlier releases, DMA channel 0 worked only with Sound Blaster 16 boards.
  • During autodetection, RAP10.DIG now checks addresses 330H and 320H, using DMA channels 5 and 6 and IRQ 9. Formerly, IRQ 5 was tested with address 320H.
  • The AIL_minimum_sample_buffer_size function could occasionally return buffer sizes below the actual minimum size when used with the SBPRO.DIG driver. This bug has been fixed.
  • An error-checking problem in the SSTEST example program could cause GP faults under rare circumstances. This bug has been fixed.
  • Updated Gravis UltraSound drivers are now available with this release. These "native mode" drivers no longer require the ULTRAMID emulation program.
  • Two new drivers, ADRV688.DIG and PROAUDIO.DIG, are supplied for use with ESS Technology's ES688 chipset and Media Vision's Pro Audio Spectrum line, respectively. Many newer systems from Compaq and other vendors include the ES688 device, which can support 16-bit stereo sound at up to 44 kHz through the use of the new ADRV688.DIG driver. PROAUDIO.DIG has been tested and found to give satisfactory performance on most systems; however, the Media Vision cards' "native mode" has never been among the most reliable of sound options, so users should be informed that the SBLASTER.DIG driver can be used with most Pro Audio Spectrum boards in the event problems occur.
  • First version of MSS for Windows is released as version 3.02 with full MSS API support for 16-bit Windows 3.1, Windows 95, and Windows NT.

Changes from version 3.0a to 3.01 (11-22-1994)

  • The AIL_background function allows an application function to tell if it is being executed from within an MSS timer, XMIDI, or callback function.
  • The new AIL_set_sample_file function is similar to the existing AIL_allocate_file_sample function, except that it operates on an existing sample handle. .VOC or .WAV files may be played using an application's own sample handles through the use of the AIL_set_sample_file function. See the API Reference for further information.
  • A powerful debugging feature has been added to the MSS API library. If an AIL_DEBUG environment variable is created with a command of the form SET AIL_DEBUG=filename, a timestamped log of virtually every MSS API call made by any subsequently-executed MSS application will be recorded to the text file or device "filename". The logfile may be examined to help diagnose and fix application errors. MSS functions called from within callback functions will not be logged, along with the functions AIL_switch_stack, AIL_restore_stack, AIL_unlock, AIL_lock, and AIL_background.
  • Digital support for the Roland RAP-10 device is now available (RAP10.DIG). This board produces extremely high-quality audio in either 8- or 16-bit, mono or stereo formats. Use the MPU401.MDI driver for MIDI support with the RAP-10.
  • Digital support for the New Media WaveJammer PCMCIA audio adapter is now available (JAMMER.ZIP). Use the OPL2.MDI driver for MIDI support with the WaveJammer.
  • Under certain circumstances, double-buffered samples could be terminated prematurely in previous releases of MSS. This problem has been fixed.
  • "Stuck" notes were occasionally reported when shutting down applications using the Roland RAP-10 and Roland SB16 MIDI daughterboards. This MIDI hardware overrun problem has been corrected by introducing a slight delay into functions which flush the XMIDI note queue, such as AIL_end_sequence and AIL_stop_sequence. This delay should not normally be perceptible at the application level.
  • Revised guidelines for audio-video synchronization have been issued with this release. The AIL_minimum_sample_buffer_size function returns the size of the smallest memory block which may be used with the double-buffering calls. Typically this value will range from 2 to 8KB; applications must ensure that their video playback engines can provide sound blocks of this size or greater. See the API Reference for further information. The DBTEST.C example program now uses AIL_minimum_sample_buffer_size to allocate its memory buffers. Note that the "Guidelines for Audio/Video Synchronization" section that appeared in earlier manual revisions is no longer applicable.
  • Under rare circumstances, MSS's built-in VMM locking calls could fail to lock the last few bytes in a module. This problem was caused by Watcom's code optimizer; a workaround is now in place.
  • The AIL_restore_interrupts function is now prototyped to return void.
  • Calls to the AIL_channel_lock function could result in crashes if any sequence handles were allocated with AIL_allocate_sequence_handle but not yet initialized with AIL_init_sequence. This problem has been fixed.
  • AIL_destroy_wave_synthesizer now releases sample handles allocated by AIL_create_wave_synthesizer. Previously, these allocated handles were lost upon destruction of the HWAVE instance.

Changes from version 3.00 to 3.0a (10-24-1994)

  • FlashTek X32 support with the Watcom compiler
  • Sound Blaster AWE32 XMIDI support (SoundFont support coming soon!)
  • Ensoniq SoundScape native-mode digital and XMIDI support
  • Updated Gravis UltraSound support
  • The AIL_set_sequence_volume function can now be used prior to calling AIL_start_sequence. Previously, AIL_start_sequence reset the sequence volume to its default value. The default sequence volume is now established by the AIL_init_sequence function, based on the MDI_DEFAULT_VOLUME preference.

Changes from version 0.0 to 3.00 (09-19-1994)

  • The complete digital audio system, with digital mixing, mono/stereo support, double-buffering, and individual control over sample pitch, volume, panning, and stereo balance. Any sample, regardless of its resolution, rate, channel count, or sign, may be played with any MSS 3.0 digital driver -- present or future!
  • Full General MIDI support, including 16-channel response for all Yamaha drivers, adjustable pitch-bend range, and information on The Fat Man's acclaimed Yamaha General MIDI instrument set.
  • Over 100 API functions for interactive music and sound effects control.
  • Complete documentation of all tools and MSS API functions.
  • Support for Watcom C32/C++32 V10.0. Versions 9.5 and earlier may also be used by recompiling the library's source code.


Miles Sound System Reference

The Miles Sound System Reference is a hyperlinked version of the Miles Sound System SDK's printed reference manual.

Chapters
Acknowledgments
Introduction
Overview for Win32: Miles on Windows XP, Vista, 2000, NT and Win9x
Overview for Win64: Miles on Windows 64 XP and Vista
Overview for Nintendo Wii
Overview for Sony PlayStation 3
Overview for Sony PlayStation 2
Overview for Microsoft Xbox
Overview for Microsoft Xbox 360
Overview for MacOS: Miles on Macintosh
Overview for DOS: Miles on DOS with 32-bit DOS Extenders
The Digital Audio Pipeline
FAQs and How Tos
Basic Types
Quick Integration Services
System Services
Memory and File Services
Timer Services
Digital Audio Services
Creative EAX 2, 3, and 4 Providers
Miles SRS Circle Surround Provider
Miles Dolby Surround Provider
Miles DTS Provider for the Sony PS2
Digital Audio Input (Recording) Services
Digital Audio Streaming Services
Digital Filter Services
CD Audio (Redbook) Services
XMIDI Services
DLS Services
Utility Services
Low-Level Sony PlayStation 2 Support Services
The RAD_IOP API for the Sony PS2
The RAD_IOP SPU Hardware Voice API for the Sony PS2
Low-Level DOS Installation Services
Low-Level DOS Support Services
Preferences
Implementing Voice Chat
Miles Sound System Tools Reference
Extended MIDI Technical Reference
MSS Device Development Kit for DOS Sound Drivers
DOS Sound Driver Generic Initialization Interface
DOS Digital Sound Driver Interface
DOS XMIDI Sound Driver Interface
DDK Support Routines for Digital Sound Drivers
DDK Support Routines for XMIDI Sound Drivers

Chapter Detail
Acknowledgments
Introduction
Overview for Win32: Miles on Windows XP, Vista, 2000, NT and Win9x
Installation for Win32
Integrating Miles into a Win32 Build Environment
Distributing Miles with Win32 Applications
Sound under Win32
Memory management under Win32
Callbacks under Win32
Sharing the CPU under Win32
Call Logging under Win32
Miles Examples for Win32
Overview for Win64: Miles on Windows 64 XP and Vista
Installation for Win64
Integrating Miles into a Win64 Build Environment
Distributing Miles with Win64 Applications
Sound under Win64
Memory management under Win64
Callbacks under Win64
Sharing the CPU under Win64
Call Logging under Win64
Miles Examples for Win64
Overview for Nintendo Wii
Installation for Nintendo Wii
Integrating Miles into a Nintendo Wii Build Environment
Distributing Miles with Nintendo Wii Applications
Sound under Nintendo Wii
Memory management under Nintendo Wii
Callbacks under Nintendo Wii
Call Logging under Nintendo
Resource Usage on the Nintendo
MSS Example for the Nintendo Wii
Overview for Sony PlayStation 3
Installation for PlayStation 3
Integrating Miles into a PlayStation 3 Build Environment
Distributing Miles with PlayStation 3 Applications
Sound under Playstation 3
Memory management under PlayStation 3
Callbacks on Playstation 3
Call Logging under PlayStation 3
Resource Usage on the Playstation 3
MSS Example for the PlayStation 3
Overview for Sony PlayStation 2
Installation for PlayStation 2
Integrating Miles into a PlayStation 2 Build Environment
Distributing Miles with PlayStation 2 Applications
Sound under Playstation 2
Memory management under PlayStation 2
Callbacks under PlayStation 2
Call Logging under PlayStation 2
Resource Usage on the Playstation 2
MSS Example for the PlayStation 2
Overview for Microsoft Xbox
Installation for Xbox
Integrating Miles into a Xbox Build Environment
Distributing Miles with Xbox Applications
Sound under Xbox
Memory management under Xbox
Callbacks under Xbox
Sharing the CPU under Xbox
Call Logging under Xbox
Miles Example for Xbox
Overview for Microsoft Xbox 360
Installation for Xbox 360
Integrating Miles into a Xbox 360 Build Environment
Distributing Miles with Xbox 360 Applications
Sound under Xbox 360
Memory management under Xbox 360
Callbacks under Xbox 360
Sharing the CPU under Xbox 360
Call Logging under Xbox 360
Miles Example for Xbox 360
Overview for MacOS: Miles on Macintosh
Installation for MacOS
Sound under MacOS
Integrating Miles into a MacOS Build Environment
Distributing Miles with MacOS Applications
Filenames on MacOS
Memory management under MacOS
Callbacks under MacOS
Sharing the CPU under MacOS
Call Logging under MacOS
Miles Examples for MacOS
Overview for DOS: Miles on DOS with 32-bit DOS Extenders
Installation for DOS
Sound under DOS
Integrating Miles into a DOS Build Environment
Distributing Miles with DOS Applications
Memory management under DOS
Callbacks under DOS
Sharing the CPU under DOS
Call Logging under DOS
Miles Examples for DOS
The Digital Audio Pipeline
FAQs and How Tos
How do I initialize the Miles Sound System for use?
How do I play a digital sound?
How do I use multi-channel sound output in Miles?
What's the best way to port my older Miles application to MSS 7?
How do I play an XMIDI or MIDI file?
How do I play an XMIDI file with a DLS instrument set?
How do I stream a file off a hard disk or CD?
How do I play a track off a CD?
How do I loop a track off a CD?
I used an older version of Miles and now my volume and pan calls are weird - what's going on? And what's with the two types of volume functions?
What kind of audio decompression does Miles support?
What is MPEG Audio and MP3?
What MP3 encoder should I use?
I can't get Miles to play an MP3, XMA, or Ogg Vorbis file - what's going on?
How can I lower the CPU hit of playing an MP3 file?
I'm getting a glitch when I loop an MP3 or ADPCM file - what can I do?
How do I apply a low-pass filter?
How do I set a DSP filter on a sample?
How much CPU do the various filters use?
How can I play two HSAMPLEs from the same memory address?
When can I free the memory I gave to MSS?
How do I start an audio file somewhere in the middle?
How do I smoothly ramp up or ramp down the volume of a sample over time?
How do I play a 3D digital sound?
My 3D sound isn't falling off like I expected - what's going on?
How can I assign 3D positions to stereo samples?
My 3D audio is a lot louder than my 2D audio - what can I do?
How do I set an environmental reverb room style?
How does Miles do sound prioritization?
On the Sony PS2, how can I use the IOP or SPU memory to hold my audio?
I can't seem to change the volume of my XMIDI sequences, what's going on?
What's the deal with callbacks - are they threads, interrupts, system timers, or what?
How much latency does Miles have?
My sound is skipping on Windows or MacOS X - what can I do?
My application is crashing - what should I try?
Where is the Miles source code? How can I rebuild it (in debug mode)?
How can I tell what version of Miles that I have?
What is the latest version of MSS?
How do I use a Unicode path on Windows?
How do I access files from a big packed file?
I'm setting a preference and it isn't having any effect - what's going on?
I want a small installation - do I need all of the files in the \redist directories?
I'm using Windows 9x or NT - do I have to call the AIL_mem_alloc_lock function?
How careful do I have to be when shutting down?
This function returns a bunch of return data, but I only want one value - is there a simpler way to use it?
The Internet voice chat example has a lot of latency or it doesn't work on my LAN - what's going on?
What are these ASI and FLT files? What is RIB?
Basic Types
S8 | describes a signed 8-bit integer.
U8 | describes an unsigned 8-bit integer.
S16 | describes a signed 16-bit integer.
U16 | describes an unsigned 16-bit integer.
S64 | describes a signed 64-bit integer.
U64 | describes an unsigned 64-bit integer.
S32 | describes a signed 32-bit integer.
U32 | describes an unsigned 32-bit integer.
SINTa | describes a signed integer that is the same size as a pointer on the current platform. Right now, only Win64 currently uses 64-bit pointers, so on everything else this is a 32-bit integer.
UINTa | describes an unsigned integer that is the same size as a pointer on the current platform. Right now, only Win64 currently uses 64-bit pointers, so on everything else this is a 32-bit integer.
F32 | describes a standard 32-bit floating-point number.
F64 | describes a standard 64-bit double-precision floating-point number.
void | describes a standard C/C++ void return type.
void * | describes a standard C/C++ untyped memory pointer.
void const * | describes a constant (unchangeable) C/C++ untyped memory pointer.
char | describes a single character type.
char * | describes a normal zero-terminated C-style string.
char const * | describes a constant (unchangeable) zero-terminated C-style string.
HDIGDRIVER | is a handle to an digital audio device.
HMDIDRIVER | is a handle to an midi output device.
HDLSDEVICE | is a handle to an DLS device.
HDIGINPUT | is a handle to an digital audio input device.
HPROVIDER | is a handle to an available RIB provider.
HDRIVERSTATE | is a handle to an open digital audio filter.
HTIMER | is a handle to a Miles timer callback.
HSAMPLE | is a handle to a digital sound sample.
HAUDIO | is a handle to a quick API handle (it can contain digital or MIDI data).
HSTREAM | is a handle to a digital audio stream.
HREDBOOK | is a handle to a CD audio (redbook) device.
HSEQUENCE | is a handle to an XMIDI sequence.
HWAVESYNTH | is a handle to an open wave synthesizer.
HDLSFILEID | is a handle to an loaded DLS instrument set.
HPROENUM | specifies a type used to enumerate through a list of RIB providers.
HINTENUM | specifies a type used to enumerate through a list of properties.
AIL_DRIVER | specifies a low-level digital or XMIDI DOS driver.
REALFAR | specifies a lower 1 MB real mode address.
LPDIRECTSOUND | describes a pointer to a DirectSound object.
LPDIRECTSOUNDBUFFER | describes a pointer to a DirectSound buffer object.
HWND | specifies a Windows window handle.
LPHWAVEOUT | specifies a pointer to a Windows waveOut device.
LPHMIDIOUT | specifies a pointer to a Windows midiOut device.
FSSpec | is a MacOS file spec structure used on Classic and Carbon.
VOID_PTR | describes a standard C/C++ untyped memory pointer.
CHAR_PTR | describes a normal zero-terminated C-style string.
Quick Integration Services
AIL_quick_startup | initializes the quick integration system.
MILES_QUICK_DIGITAL_OPEN | describes how to open the digital audio system.
MILES_QUICK_MIDI_OPEN | describes how to open the MIDI system.
AIL_quick_shutdown | closes the quick integration API.
AIL_quick_load | loads a sound file, returning a handle that can be used with the other quick API functions.
AIL_quick_fss_load | loads a sound file from a Mac file spec, returning a handle that can be used with the other quick API functions.
AIL_quick_load_mem | loads a sound file that is already loaded into memory, returning a handle that can be used with the other quick API functions.
AIL_quick_load_named_mem | loads a sound file that is already loaded into memory, with a filename hint, returning a handle that can be used with the other quick API functions.
AIL_quick_copy | copies an audio handle from an already-loaded audio handle.
AIL_quick_unload | unloads a sound handle previously loaded with AIL_quick_load or AIL_quick_load_and_play.
AIL_quick_play | starts the playback of an audio file previously loaded with AIL_quick_load.
AIL_quick_halt | stops a currently playing audio handle.
AIL_quick_status | returns the status of an audio handle.
MILES_QUICK_STATUS | describes the status of a Quick API audio handle.
AIL_quick_load_and_play | loads a sound file into a handle and begins playing it immediately.
AIL_quick_fss_load_and_play | loads a Mac file spec sound into a handle and begins playing it immediately.
AIL_quick_type | returns the type of an audio handle.
MILES_QUICK_TYPE | describes the data in a Quick API audio handle.
AIL_quick_set_volume | controls the volume of an audio handle.
AIL_quick_set_speed | controls the playback rate of an audio handle.
AIL_quick_ms_length | returns the total length in milliseconds of an audio handle.
AIL_quick_ms_position | returns the current position in milliseconds of an audio handle.
AIL_quick_set_ms_position | changes current playback position in milliseconds of the specified audio handle.
AIL_quick_set_reverb_levels | changes the reverb levels of a digital audio sample, or a MIDI playing through the software synthesizer.
AIL_quick_set_low_pass_cut_off | applies a low-pass filter to the digital audio sample.
AIL_quick_handles | returns the MSS digital driver and MIDI driver handles.
System Services
AIL_set_redist_directory | sets the location of your application's Miles directory.
Register_RIB | registers a static library RIB interface on non-Win32 platforms such as Xbox, Sony Playstation 2 or DOS.
AIL_startup | initializes the Miles Sound System and prepares for the installation and use of sound drivers.
AIL_shutdown | shuts down all active sound drivers, restores normal system timer operation, and disconnects the API timer interrupt handler.
AIL_MSS_version | returns the version of the Miles library.
AIL_serve | provides periodic foreground service to the Miles Sound System to avoid `starvation` during periods when the application does not yield control frequently.
AIL_set_preference | controls certain internal parameters used by the MSS system.
AIL_get_preference | queries the current MSS internal parameters.
AIL_last_error | returns a string describing the last MSS error.
AIL_background | allows an application function to determine if it is currently running in `background` mode from an interrupt or thread, or if it is currently running in the `foreground`.
AIL_register_trace_callback | registers an application function to receive debug trace message traffic from MSS.
AILTRACECB | specifies a user-defined debug-trace callback.
AIL_platform_property | retrieves and/or sets platform-specific properties for the Miles Sound System.
MSS_PLATFORM_PROPERTY | is a list of available platform-specific property identifiers for use with the AIL_platform_property function.
Memory and File Services
AIL_mem_alloc_lock | allocates a locked block of memory.
AIL_mem_free_lock | frees a pointer previously allocated with AIL_mem_alloc_lock or AIL_file_read.
AIL_file_read | loads a data file into the specified memory address, optionally allocating the memory as well.
AIL_file_fss_read | loads a data file spec into the specified memory address, optionally allocating the memory as well.
AIL_file_write | creates a new data file and fills it with the specified data.
AIL_file_fss_write | creates a new MacOS data file spec and fills it with the specified data.
AIL_file_fss_attrib_write | creates a new MacOS data file spec and fills it with the specified data.
AIL_WAV_file_write | creates a new Microsoft .WAV file.
AIL_WAV_file_fss_write | creates a new MacOS .WAV file spec.
AIL_file_size | returns the size of the specified data file.
AIL_file_fss_size | returns the size of the specified MacOS data file spec.
AIL_file_error | returns the last file I/O error from AIL_file_read, AIL_file_write, or AIL_file_size.
MILES_FILE_ERRORS | describes an error encountered by one of the Miles file I/O functions.
AIL_mem_use_malloc | replaces the default memory allocation routines.
AIL_mem_use_free | replaces the default memory freeing routine.
AILMALLOCCB | specifies a pointer to a user-defined memory allocation callback.
AILFREECB | specifies a pointer to a user-defined memory release callback.
AIL_set_file_callbacks | replaces the synchronous (blocking) file I/O functions that Miles uses for AIL_file_read, AIL_file_size, and the high-level streaming functions.
AIL_set_file_async_callbacks | replaces the file I/O handlers that Miles uses for its high-level streaming functions on certain platforms.
AIL_file_open_callback | specifies a user-replaceable callback handler to open a file in MSS.
AIL_file_close_callback | specifies a user-replaceable callback handler to close a file.
AIL_file_seek_callback | specifies a user-replaceable callback handler to seek in a file.
MILES_FILE_SEEK_TYPE | describes the type of seek to perform.
AIL_file_read_callback | specifies a user-replaceable callback handler to read from a file.
AIL_file_async_read_callback | specifies a user-replaceable callback handler to initiate asynchronous reads from a file.
AIL_file_async_status_callback | specifies a user-replaceable callback handler to poll for completion of an asynchronous read.
AIL_vmm_lock | locks the specified memory range under DOS.
AIL_vmm_unlock | unlocks a piece of memory previously locked with AIL_vmm_lock.
AIL_vmm_lock_range | locks the specified memory range under DOS.
AIL_vmm_unlock_range | unlocks a piece of memory previously locked with AIL_vmm_lock_range.
Timer Services
AIL_ms_count | returns a millisecond accurate timer count (one thousand ticks per second).
AIL_us_count | returns a microsecond accurate timer count (one million ticks per second).
AIL_register_timer | registers a callback function callback_fn to receive asynchronous time-slice service from a timer, and returns a handle HTIMER which may be used to start, stop, and program the function's assigned timer.
AILTIMERCB | specifies a user-defined timer callback.
AIL_set_timer_user | instructs the MSS timer dispatcher to pass the value user to the timer callback function associated with the timer handle timer.
AIL_set_timer_period | programs a timer for callback service at periods ranging from 1 microsecond to 1,000,000,000 microseconds (approximately 15 minutes).
AIL_set_timer_frequency | programs a timer for callback service at frequencies ranging from 1 Hz (Hertz, or cycles per second) to 1,000,000 Hz.
AIL_set_timer_divisor | programs a timer for callback service at a rate which is given in terms of the constant value that would normally be used to program the IBM PC's 8253 Programmable Interval Timer chip for the desired interrupt rate, if the application were to access the chip directly.
AIL_interrupt_divisor | returns the current value used internally by the Miles Sound System's Timer Services to program the IBM PC's 8253 Programmable Interval Timer chip for periodic INT 8 (IRQ 0) service.
AIL_start_timer | initiates or resumes periodic time-slice interrupt service to the callback function registered to timer.
AIL_stop_timer | stops periodic time-slice interrupt service to the callback function registered to timer.
AIL_release_timer_handle | stops periodic time-slice interrupt service to the callback function registered to timer, and releases the timer's handle.
AIL_get_timer_highest_delay | returns the highest delay in timer servicing under Win 32.
AIL_delay | suspends foreground program execution.
AIL_lock | suspends timer service to all MSS drivers and application callback functions until a matching call to AIL_unlock is made.
AIL_unlock | resumes timer service to all MSS drivers and application callback functions after a matching call to AIL_lock.
AIL_start_all_timers | initiates or resumes periodic time-slice interrupt service to the callback functions registered to all active timer handles.
AIL_stop_all_timers | stops periodic time-slice interrupt service to the callback functions registered to all active timer handles.
AIL_release_all_timers | stops periodic time-slice interrupt service to the callback functions registered to all active timer handles, and releases all active timer handles.
Digital Audio Services
AIL_open_digital_driver | opens a digital driver to play 2D digital audio.
MSS_SPEAKER | may be used to specify either a source (HSAMPLE/HSTREAM) channel or an HDIGDRIVER's destination speaker output channel.
MSS_MC_SPEC | specifies an output channel-configuration option for use with AIL_open_digital_driver or AIL_quick_startup.
MILES_OPEN_DIGITAL_FLAGS | specifies open flags for the AIL_open_digital_driver function.
AIL_close_digital_driver | shuts down and closes an audio driver which was opened by a previous call to AIL_open_digital_driver.
AIL_digital_handle_release | temporarily releases the hardware digital handle (either the HWAVEOUT handle, the DirectSound object, or the Sound Manager buffer) back to the system.
AIL_digital_handle_reacquire | attempts to reacquire hardware digital handle (either the HWAVEOUT handle, the DirectSound object, or the Sound Manager buffer) from the system.
AIL_set_DirectSound_HWND | assigns the HWND to use for DirectSound's focus control.
AIL_HWND | returns the HWND that MSS has detected as your primary HWND.
AIL_set_digital_master_volume_level | establishes an overall `master volume` value which is used to scale the volumes of all subsequent digital audio samples.
AIL_digital_master_volume_level | returns the current digital master volume setting in use.
AIL_set_digital_master_reverb | sets the global reverb settings to use.
MILES_ROOM_TYPE | specifies a room type to use for the environmental reverb.
AIL_digital_master_reverb | retrieves the global reverb settings to use.
AIL_set_digital_master_reverb_levels | establishes the overall `master reverb` levels which are used to scale the levels of the reverb of all subsequent digital audio samples.
AIL_digital_master_reverb_levels | retrieves the overall `master reverb` levels.
AIL_set_speaker_reverb_levels | sets the global wet and dry reverb-response scalars at one or more speakers.
AIL_speaker_reverb_levels | returns three arrays describing the wet and dry reverb-response scalars at all speakers, plus the speaker channel identifiers themselves.
AIL_calculate_3D_channel_levels | gives your application direct access to the Miles 3D sound-positioner function.
MSSVECTOR3D
AIL_allocate_sample_handle | searches for a free sample handle and returns it to the application for use in the playback of digital audio data.
AIL_release_sample_handle | releases a sample handle previously allocated with AIL_allocate_sample_handle.
AIL_init_sample | prepares a sample handle for playback of audio data.
AIL_set_sample_address | specifies the starting address and length for a raw data sample.
AIL_set_sample_file | initializes a sample's address, length, type, and flags to prepare for playback of memory-resident sound data.
AIL_set_named_sample_file | initializes a sample's address, length, type, and flags to prepare for playback of a memory-resident sound data.
AIL_set_sample_info | initializes a sample's address, length, type, and flags to prepare for playback of memory-resident sound data.
MILES_DIGITAL_FORMAT | describes the type of digital audio.
MILES_DIGITAL_FLAGS | describes the layout of digital audio.
AIL_start_sample | starts playback of a sample from its beginning.
AIL_stop_sample | stops playback of a sample.
AIL_resume_sample | resumes playback of a sample which was previously stopped.
AIL_end_sample | terminates playback of a sample, setting its status to SMP_DONE.
AIL_set_sample_playback_rate | sets a sample's playback rate in hertz.
AIL_sample_playback_rate | returns the current sample playback rate.
AIL_set_sample_volume_pan | controls a sample's playback volume level and pan.
AIL_sample_volume_pan | returns the current sample volume and pan, from 0 to 1.0.
AIL_set_sample_reverb_levels | changes the reverb levels of a digital audio sample.
AIL_sample_reverb_levels | retrieves the reverb levels of a digital audio sample.
AIL_set_sample_low_pass_cut_off | applies a low-pass filter to the digital audio sample.
AIL_sample_low_pass_cut_off | retrieves the current low-pass cutoff setting.
AIL_set_sample_51_volume_pan | controls a sample's playback volume and pan values when using multichannel discrete output modes.
AIL_sample_51_volume_pan | returns the current sample 5.1 volumes and pan, from 0 to 1.0, resulting from a prior call to AIL_set_sample_51_volume_pan or AIL_set_sample_51_volume_levels.
AIL_set_sample_volume_levels | controls a sample's playback volume levels.
AIL_sample_volume_levels | returns the current sample volumes, from 0 to 1.0.
AIL_set_sample_channel_levels | scales the output contribution from each source channel in the specified HSAMPLE to each speaker.
AIL_sample_channel_levels | returns an array of level-scaling factors for one or more combinations of source channels and destination speakers.
AIL_sample_output_levels | returns the final mixer level-scaling factors for one or more combinations of source channels and destination speakers.
AIL_set_sample_51_volume_levels | controls a sample's playback volume levels when using multichannel discrete output modes.
AIL_sample_51_volume_levels | returns the current sample 5.1 volumes, from 0 to 1.0, on discrete multichannel platforms.
AIL_set_sample_3D_distances | sets the minimum and maximum distances for a given sample handle.
AIL_sample_3D_distances | returns the current minimum and maximum distances for the specified sample handle.
AIL_set_sample_3D_cone | sets the sound emission cone on a sample.
AIL_sample_3D_cone | retrieves the current sound emission cone of a sample.
AIL_set_sample_occlusion | sets the occlusion for the specified 3D sample.
AIL_sample_occlusion | retrieves the current occlusion level of the given sample.
AIL_set_sample_obstruction | sets the obstruction for the specified 3D sample.
AIL_sample_obstruction | retrieves the current obstruction level of the given sample.
AIL_set_sample_exclusion | sets the exclusion for the specified 3D sample.
AIL_sample_exclusion | retrieves the current exclusion level of the given sample.
AIL_set_listener_3D_position | sets the three-dimensional position of the 3D listener.
AIL_listener_3D_position | retrieves the current 3D position of the 3D listener.
AIL_set_listener_3D_velocity | sets the current velocity of the 3D listener.
AIL_listener_3D_velocity | retrieves the current velocity of the 3D listener.
AIL_set_listener_3D_velocity_vector | sets the current velocity of the 3D listener.
AIL_update_listener_3D_position | updates the 3D listener's position based on its previously set velocity and the specified delta time in milliseconds.
AIL_set_listener_3D_orientation | specifies the orientation of the 3D listener.
AIL_listener_3D_orientation | retrieves the orientation of the 3D listener.
AIL_set_sample_3D_position | sets a sample's current position in 3D space.
AIL_sample_3D_position | retrieves the current 3D position of a 3D sample.
AIL_set_sample_3D_velocity | sets the current velocity of a 3D sample.
AIL_sample_3D_velocity | retrieves the current velocity of a 3D sample.
AIL_set_sample_3D_velocity_vector | sets the current velocity of a 3D sample.
AIL_update_sample_3D_position | updates a 3D sample's position based on its previously-set velocity and the specified delta time in milliseconds.
AIL_set_sample_3D_orientation | specifies the orientation of a 3D sample.
AIL_sample_3D_orientation | retrieves the orientation of a 3D sample.
AIL_set_room_type | sets the room type that the listener is currently in.
AIL_room_type | returns the current room type.
AIL_set_3D_rolloff_factor | sets the driver's global 3D rolloff factor.
AIL_3D_rolloff_factor | returns the driver's current 3D rolloff factor.
AIL_set_3D_doppler_factor | sets the driver's global 3D Doppler factor.
AIL_3D_doppler_factor | returns the driver's current 3D Doppler factor.
AIL_set_3D_distance_factor | sets the driver's global 3D distance factor.
AIL_3D_distance_factor | returns the driver's current 3D distance factor.
AIL_set_sample_loop_count | arranges for a sample to be restarted immediately upon completion, for a total of two or more iterations.
AIL_sample_loop_count | returns the number of loop iterations remaining for the given sample.
AIL_set_sample_loop_block | arranges for a sub-block of a sample to be looped.
AIL_sample_loop_block | returns the beginning and ending loop offsets previously passed to AIL_set_sample_loop_block.
AIL_set_sample_position | adjusts the playback position of a sample.
AIL_sample_position | reports the current playback position of a sample.
AIL_set_sample_ms_position | adjusts the playback position of a sample.
AIL_sample_ms_position | reports the current playback position and length of a sample in milliseconds.
AIL_sample_status | returns the status of a given sample handle.
MILES_DIGITAL_STATUS | describes the current state of the digital audio.
AIL_set_sample_user_data | sets a value for one of eight user data entries associated with each sample handle.
AIL_sample_user_data | retrieves a value for one of eight user data entries associated with each sample handle.
AIL_minimum_sample_buffer_size | returns the minimum usable buffer size for use with the low-level streaming function AIL_load_sample_buffer.
AIL_sample_buffer_available | checks to see if any of the buffers associated with a sample handle are ready to be filled with new audio data by the AIL_load_sample_buffer function.
AIL_load_sample_buffer | sets the address and length for one of the low-level streaming buffers associated with a sample handle, enabling low-level streaming mode for that sample handle.
AIL_sample_buffer_info | returns detailed information about the status of the low-level streaming buffers for the specified sound handle.
AIL_sample_buffer_count | returns the number of low-level streaming buffers associated with a sample.
AIL_set_sample_buffer_count | sets the number of low-level streaming buffers available for use with a given sample handle.
AIL_sample_channel_count | returns information about the source channels associated with a sample.
AIL_sample_granularity | returns the granularity of a sample in bytes.
AIL_set_sample_adpcm_block_size | sets the block size for the IMA ADPCM data.
AIL_digital_CPU_percent | returns the percentage of total CPU being spent in the Miles digital processing loop.
AIL_digital_latency | returns the approximate latency of a sound if it were started immediately.
AIL_set_speaker_configuration | establishes the listener-relative location of the speaker array, and the falloff power factor used for sample spatialization.
AIL_speaker_configuration | returns an array of 3D vectors describing the listener-relative locations of the array of speakers associated with the current output format, plus some additional information about the format.
AIL_enumerate_output_filter_driver_properties | enumerates the possible driver-level properties of an output filter.
AIL_enumerate_output_filter_sample_properties | enumerates the possible sample-level properties of an output filter.
AIL_output_filter_driver_property | retrieves and/or sets driver-level properties for an output filter.
AIL_register_SOB_callback | arranges for callback service to be provided to an application's function just before a block of sample data is merged into the hardware buffer.
AILSAMPLECB | specifies a user-defined digital audio callback.
AIL_register_EOB_callback | arranges for callback service to be provided to an application function immediately upon reaching the end of a sample buffer.
AIL_register_EOS_callback | arranges for callback service to be provided to an application function immediately upon reaching the end of a sample.
AILFALLOFFCB | specifies a user-defined 3D distance-based falloff function callback.
AIL_register_falloff_function_callback | allows an application to override the system's default distance-based attenuation calculations for 3D-enabled samples.
AIL_active_sample_count | returns the number of currently-playing samples.
AIL_digital_configuration | returns information about the specified digital driver.
AIL_get_DirectSound_info | returns the pointers to the DirectSound object currently being used by MSS.
AIL_install_DIG_INI | installs and initializes the currently selected MSS .DIG driver file under DOS.
MILES_INSTALL_STATUS | specifies possible results from loading a DOS driver.
AIL_install_DIG_driver_file | installs and initializes an MSS-compatible .DIG driver file under DOS.
IO_PARMS | indicates specific hardware settings to use when installing a digital driver
Creative EAX 2, 3, and 4 Providers
Creative's EAX 2 Properties
Creative's EAX 3 Properties
Creative's EAX 4 Properties
EAX_SAMPLE_SLOT_VOLUME | used to control the sound levels for a slot that the sample should play to
EAX_SAMPLE_SLOT_VOLUMES | used to control the sound levels for each the two possible slots that the sample can play into
EAX_REVERB | used to control the environmental reverb filter in the EAX 4 3D provider
EAX_AUTOGAIN | used to control the automatic gain control filter in the EAX 4 3D provider
EAX_AUTOWAH | used to control the autowah filter in the EAX 4 3D provider
EAX_CHORUS | used to control the chorus filter in the EAX 4 3D provider
EAX_DISTORTION | used to control the distortion filter in the EAX 4 3D provider
EAX_ECHO | used to control the echo filter in the EAX 4 3D provider
EAX_EQUALIZER | used to control the equalizer filter in the EAX 4 3D provider
EAX_FLANGER | used to control the flange filter in the EAX 4 3D provider
EAX_FSHIFTER | used to control the frequency shifter filter in the EAX 4 3D provider
EAX_VMORPHER | used to control the vocal morpher filter in the EAX 4 3D provider
EAX_PSHIFTER | used to control the pitch shifter filter in the EAX 4 3D provider
EAX_RMODULATOR | used to control the ring modulator filter in the EAX 4 3D provider
Miles SRS Circle Surround Provider
Miles SRS Circle Surround Provider
Miles Dolby Surround Provider
Miles Dolby Surround Provider
Miles DTS Provider for the Sony PS2
Miles DTS Provider for the Sony PS2
Digital Audio Input (Recording) Services
AIL_open_input | opens a digital input channel (usually from the microphone) to receive input digital audio data.
AIL_INPUT_INFO | specifies the details for performing digital input.
AIL_input_callback | specifies a user callback that is called as audio data is received by the input device.
AIL_close_input | closes a digital input handle.
AIL_set_input_state | controls whether the digital input channel is actively recording or not.
AIL_get_input_info | returns the information structure used to open the digital input channel.
Digital Audio Streaming Services
AIL_open_stream | opens a stream handle based on a supported file (.WAV, Ogg Vorbis, XMA, or MP3, and others).
AIL_close_stream | closes a stream handle.
AIL_service_stream | services the given stream handle.
AIL_auto_service_stream | turns auto-servicing on or off for a stream handle (it's turned on by default).
AIL_start_stream | starts playback of the specified stream.
AIL_pause_stream | pauses the playback of the specified stream handle.
AIL_stream_sample_handle | returns the underlying HSAMPLE associated with a given HSTREAM instance.
AIL_set_stream_loop_count | arranges for a stream to be restarted immediately upon completion, for a total of two or more iterations.
AIL_stream_loop_count | returns the number of loop iterations remaining for the given stream.
AIL_set_stream_loop_block | arranges for a sub-block of a stream to be looped.
AIL_set_stream_position | adjusts the playback position of a stream.
AIL_stream_position | reports the current playback position of a stream.
AIL_set_stream_ms_position | adjusts the playback position of a stream.
AIL_stream_ms_position | reports the total length and the current playback position of a stream.
AIL_stream_status | returns the status of a given stream handle.
AIL_set_stream_user_data | sets a value for one of eight user data entries associated with each stream handle.
AIL_stream_user_data | retrieves a value for one of eight user data entries associated with each stream handle.
AIL_stream_info | returns information about the given stream handle.
AIL_register_stream_callback | arranges for callback service to be provided to an application function immediately upon reaching the end of a stream.
AILSTREAMCB | specifies a user-defined digital audio stream callback.
Digital Filter Services
AIL_find_filter | tries to locate a filter by its name.
AIL_enumerate_filters | enumerates the available filter processors for display or for opening.
AIL_open_filter | opens a filter to prepare it for use.
AIL_close_filter | closes a previously opened filter.
AIL_set_sample_processor | assigns the filter or mixer stages for a specific sample.
AIL_sample_processor | returns the current filter or mixer stage provider for a specific sample.
AIL_digital_driver_processor | returns the current default filter or mixer stage provider for a specific driver.
AIL_digital_output_filter | returns the output filter (either per-voice or matrix) provider for a specific driver.
SAMPLESTAGE | describes the stage in the sample pipeline to install the filter on.
AIL_set_digital_driver_processor | assigns the default filter or mixer stages for a digital driver.
DIGDRVSTAGE | describes the stage in the driver pipeline to install the filter on.
AIL_enumerate_filter_properties | enumerates a filter's provider-level properties.
RIB_INTERFACE_ENTRY | specifies a structure that contains RIB property information.
RIB_ENTRY_TYPE | describes the type of the RIB entry.
RIB_DATA_SUBTYPE | describes the variable type of the RIB entry.
AIL_enumerate_filter_sample_properties | enumerates the possible sample-level filter properties.
AIL_enumerate_sample_stage_properties | enumerates the possible sample-level filter properties for the filter currently assigned to a given HSAMPLE processing stage.
AIL_filter_property | retrieves and/or sets the current value of the specified provider-level property.
AIL_sample_stage_property | retrieves and/or sets the current value of the specified sample-level property.
Capture Filter
Low-Pass Filter
EAX Compatible Reverb
High-Pass Filter
Band-Pass Filter
All-Pass Filter
Resonator Filter
Delay Filter
Parametric Equalizer Filter
Shelving Equalizer Filter
Compressor Filter
Gain Block Filter
Volume Ramp Filter
Ring-Amplitude Modulator Filter
Phaser Filter
Chorus Filter
Flange Filter
CD Audio (Redbook) Services
AIL_redbook_open | opens a Red Book CD-audio device.
AIL_redbook_open_drive | opens a Red Book CD-audio device from a drive letter.
AIL_redbook_open_volume | opens a Red Book CD-audio device from a MacOS volume name.
AIL_redbook_close | closes the handle to the Red Book device.
AIL_redbook_eject | ejects the CD currently inserted in the CD-ROM.
AIL_redbook_retract | retracts the CD tray back into the CD-ROM.
AIL_redbook_id | returns an ID that will uniquely identify the CD currently inserted in the Red Book device.
AIL_redbook_status | returns the current status of the specified Red Book device.
MILES_REDBOOK_STATUS | specifies the redbook device status.
AIL_redbook_tracks | returns the number of audio tracks on the inserted CD.
AIL_redbook_track_info | returns the starting and ending millisecond offsets for a given track.
AIL_redbook_position | returns the current position in milliseconds of a playing Red Book device.
AIL_redbook_track | returns the currently play audio track number.
AIL_redbook_play | begins playback of an audio CD at the specified offset.
AIL_redbook_stop | stops playback of a Red Book CD-audio device.
AIL_redbook_pause | pauses the playback of a Red Book CD-audio device.
AIL_redbook_resume | resumes the playback of a Red Book CD-audio device.
AIL_redbook_set_volume_level | controls the volume level of the Red Book CD-audio device.
AIL_redbook_volume_level | retrieves the volume level of the Red Book CD-audio device.
XMIDI Services
AIL_open_XMIDI_driver | opens an driver handle to play XMIDI data files through.
MILES_OPEN_XMIDI_FLAGS | specifies open flags for the AIL_open_XMIDI_driver function.
AIL_close_XMIDI_driver | shuts down and closes a MIDI music driver which was opened by a previous call to AIL_open_XMIDI_driver.
AIL_MIDI_handle_release | temporarily releases the hardware MIDI handle (the HMIDIOUT handle or the QuickTime MIDI handle) back to the system.
AIL_MIDI_handle_reacquire | attempts to reacquire the hardware MIDI handle (the HMIDIOUT handle or the QuickTime MIDI handle) from the system.
AIL_set_XMIDI_master_volume | establishes an overall `master volume` value which is used to scale the volumes of all subsequent XMIDI note events in all sequences.
AIL_XMIDI_master_volume | returns the current XMIDI master volume setting in use.
AIL_allocate_sequence_handle | searches for a free sequence handle and returns it to the application for use in the playback of XMIDI audio data.
AIL_release_sequence_handle | frees a sequence handle for later allocation by AIL_allocate_sequence_handle.
AIL_init_sequence | prepares a sequence handle for playback of XMIDI sequence data, and allows the application to specify the starting address and sequence number of the XMIDI sequence to be played.
AIL_start_sequence | starts playback of a sequence from its beginning.
AIL_stop_sequence | stops playback of a sequence.
AIL_resume_sequence | resumes playback of a sequence which was previously stopped.
AIL_end_sequence | terminates playback of a sequence, setting its status to SEQ_DONE<*MILES_SEQUENCE_STATUS>.
AIL_set_sequence_tempo | specifies an increase or decrease in the normal playback tempo of a sequence.
AIL_sequence_tempo | returns the current relative tempo percentage for a sequence.
AIL_set_sequence_volume | establishes a scaling factor for the value of each MIDI Part Volume Control Change (controller 7) event occurring in a sequence.
AIL_sequence_volume | returns the current sequence volume scaling value, from 0 (minimum) to 127 (maximum).
AIL_set_sequence_loop_count | arranges for a sequence to be restarted immediately upon completion, for a total of two or more iterations.
AIL_sequence_loop_count | returns the number of loop iterations remaining for the given sequence.
AIL_branch_index | moves a sequence's data pointers to the location of a specified XMIDI Sequence Branch Index controller.
AIL_sequence_position | returns the number of beats and measures elapsed since a given XMIDI sequence began playing.
AIL_set_sequence_ms_position | moves the current playback position of a sequence to the specified millisecond count.
AIL_sequence_ms_position | returns the current playback position and length of the sequence in milliseconds.
AIL_set_sequence_user_data | sets a value for one of eight user data entries associated with each sequence handle.
AIL_sequence_user_data | retrieves a value for one of eight user data entries associated with each sequence handle.
AIL_sequence_status | returns the status of a given sequence handle.
MILES_SEQUENCE_STATUS | indicates the status of an XMIDI handle.
AIL_create_wave_synthesizer | creates a `virtual wave synthesizer` by associating an XMIDI driver with a digital audio driver and a library file containing digital audio samples assigned to various MIDI patches.
AIL_destroy_wave_synthesizer | destroys a `virtual wave synthesizer` instance created by a previous call to the AIL_create_wave_synthesizer function.
AIL_MDI_driver_type | reports the MIDI synthesis technology available with a specified.
MILES_MDI_DRIVER_TYPE | describes the type of DOS MIDI driver.
AIL_set_GTL_filename_prefix | informs MSS of the prefix portion of all Global Timbre Library filenames which are associated with a particular application.
AIL_timbre_status | checks to see if a given timbre (synthesizer instrument) is loaded.
AIL_install_timbre | forces the driver to install a single timbre (synthesizer instrument), allowing it to be used for performance in a channel of an Extended MIDI (XMIDI) sequence which contains an XMIDI Patch Bank Select controller (114) with the value bank followed by a MIDI Program Change (Patch) message with the value patch.
AIL_protect_timbre | prevents the timbre bank, patch from being discarded from the synthesizer memory or local timbre cache.
AIL_unprotect_timbre | disables timbre protection for the timbre bank, patch, subjecting the timbre to the action of the normal timbre replacement algorithm.
AIL_active_sequence_count | returns the number of currently-playing sequences.
AIL_controller_value | returns any current MIDI Control Change value for any of the channels used in the specified sequence.
MILES_MIDI_VALUE | specifies a MIDI controller that can queried.
AIL_channel_notes | returns the number of notes currently turned `on` in a given MIDI channel.
AIL_register_prefix_callback | registers an application function to be called whenever an XMIDI Callback Prefix controller (108) is encountered in a playing XMIDI sequence.
AILPREFIXCB | specifies a user-defined XMIDI prefix callback.
AIL_register_trigger_callback | registers an application function to be called whenever an XMIDI Callback Trigger controller (119) is encountered in a playing XMIDI sequence.
AILTRIGGERCB | specifies a user-defined XMIDI trigger callback.
AIL_register_sequence_callback | registers an application function to be called immediately upon completion of playback of an XMIDI sequence.
AILSEQUENCECB | specifies a user-defined XMIDI end of sequence callback.
AIL_register_event_callback | registers an application function to be called immediately prior to processing each XMIDI or MIDI Channel Voice message event associated with a given driver.
AILEVENTCB | specifies a user-defined XMIDI event callback.
AIL_register_beat_callback | registers an application function to be called each time the relative beat count changes in any sequence played with the given driver.
AILBEATCB | specifies a user-defined XMIDI beat callback.
AIL_register_timbre_callback | registers an application function to be called immediately prior to installing a timbre with AIL_install_timbre or AIL_init_sequence.
AILTIMBRECB | specifies a user-defined XMIDI timbre installation callback.
AIL_register_ICA_array | allows the application to declares an array of 128 bytes whose entries may be used to replace XMIDI or MIDI controller values whose controller events are preceded by an XMIDI Indirect Controller Prefix controller (115).
AIL_lock_channel | returns an individual MIDI channel number to the application for direct MIDI message transmission, preventing any XMIDI sequence from utilizing that physical channel until its release with AIL_release_channel.
AIL_release_channel | returns a MIDI channel previously locked with AIL_lock_channel to the sequence which formerly `owned` it, if any.
AIL_map_sequence_channel | causes all events in a given sequence which are associated with a given MIDI channel seq_channel to be transmitted instead on a `remapped` MIDI channel new_channel.
AIL_true_sequence_channel | returns the physical MIDI channel number which receives MIDI and XMIDI messages transmitted on a logical channel sequence_channel by a given sequence S.
AIL_send_channel_voice_message | transmits any desired MIDI Channel Voice message on any MIDI channel.
AIL_send_sysex_message | transmits a System Exclusive message to a MIDI device driver.
AIL_midiOutOpen | assigns a Windows Multimedia Extensions low-level midiOut driver (or the MIDI Mapper device) to the Windows MSS API for MIDI music performance.
AIL_install_MDI_INI | installs and initializes the currently selected MSS .MDI driver file for XMIDI music performance under DOS.
AIL_install_MDI_driver_file | installs and initializes an MSS-compatible .MDI driver file for XMIDI music performance under DOS.
DLS Services
AIL_DLS_open | opens a handle to a downloadable sample device.
AIL_DLS_close | closes a previously opened DLS device.
MILES_DLS_CLOSE_FLAGS | specifies optional closing flags to AIL_DLS_close.
AIL_DLS_load_file | loads an uncompressed DLS file into the specified DLS device.
AIL_DLS_load_memory | loads an uncompressed DLS file memory image into the specified DLS device.
AIL_DLS_unload | unloads a previously loaded DLS file ID and makes the sample memory available for other DLS files.
MILES_DLS_UNLOAD | describes optional DLS unload flags.
AIL_DLS_compact | compacts the memory of a hardware DLS device.
AIL_DLS_get_info | retrieves information about the specified DLS device.
AILDLSINFO | specifies the details for a DLS device.
AIL_DLS_sample_handle | returns the underlying HSAMPLE associated with a given DLS synthesizer instance.
Utility Services
AIL_file_type | returns the file type of the specified file image.
MILES_FILE_TYPE | describes the type of a file.
AIL_file_type_named | returns the file type of the specified file image using a filename hint.
AIL_WAV_info | retrieves the audio format information for the specified file image.
AILSOUNDINFO | specifies audio format details.
AIL_process_digital_audio | provides high-level access to the Miles sound mixer.
AILMIXINFO
AIL_size_processed_digital_audio | provides a way to determine how much output memory is necessary for a given set of input mix data.
AIL_compress_ADPCM | compresses the digital sound described by the info structure into an IMA ADPCM wave file image.
AIL_decompress_ADPCM | decompresses the IMA ADPCM digital sound described by the info structure into a standard PCM wave file image.
AIL_compress_ASI | compresses a digital sound with an ASI encoder capable of writing the file type described by the filename_ext parameter.
AILLENGTHYCB | specifies a user-defined callback that gets called during lengthy Miles operations.
MILES_LENGTHY_STATE | indicates the current stage of the lengthy operation.
AILCODECSETPROP | provides a way for ASI properties to be set during a compression or decompression.
AIL_decompress_ASI | decompresses a digital sound with the ASI decoder for the passed file extension and returns a standard PCM wave file image.
AIL_MIDI_to_XMI | converts Standard MIDI Format 0 and Format 1 sequence files to the Extended MIDI (XMIDI) format.
MILES_MIDI_TO_XMI_FLAGS | specifies optional conversion flags for the AIL_MIDI_to_XMI function.
AIL_compress_DLS | compresses a DLS file with either IMA ADPCM compression or with an ASI encoder specified by the compress_ext parameter.
AIL_extract_DLS | extracts and decompresses the DLS data from a loaded MLS file or merged XMIDI file.
AIL_find_DLS | returns pointers and sizes to the DLS and XMIDI chunks inside a merged XMIDI file image.
AIL_merge_DLS_with_XMI | merges an XMIDI file and a DLS or MLS file together.
AIL_filter_DLS_with_XMI | filters out unused instruments in a DLS file given one or more XMIDI files.
MILES_FILTER_DLS_FLAGS | specifies options to use when filtering DLS instrument sets with an XMIDI file.
AIL_list_MIDI | creates a detailed listing of a MIDI file.
MILES_LIST_MIDI_FLAGS | specifies flags to use when listing a MIDI file.
AIL_list_DLS | creates a detailed listing of a DLS or MLS file.
MILES_LIST_DLS_FLAGS | specifies flags to use when listing a DLS file.
AIL_inspect_MP3 | obtains some basic information about the structure of an MPEG-1 Layer 3 audio file, and prepares for optional header enumeration.
AIL_enumerate_MP3_frames | obtains information about successive frames from an MPEG-1 Layer 3 audio file.
MP3_INFO
Low-Level Sony PlayStation 2 Support Services
AIL_set_scratchpad_policy | specifies whether (and how) MSS can use the PS2's scratchpad RAM.
AIL_scratchpad_policy | returns the current MSS scratchpad-usage policy.
MSS_RESOURCE_POLICY | specifies a usage policy for the AIL_set_scratchpad_policy function.
The RAD_IOP API for the Sony PS2
RAD_IOPStartUp | opens the RAD_IOP API for use.
SOUND_CORE_FLAGS | Specifies the sound flags that RAD_IOP should use.
RAD_IOPMemoryAmount | returns the amount of IOP memory in bytes that RAD_IOP will need.
RAD_IOPShutDown | closes the RAD_IOP library.
RAD_IOPQueueAsyncOpenFile | asynchronously opens a file handle.
RAD_IOP_ASYNC_OPEN_DATA | is a structure used with the RAD_IOPQueueAsyncOpenFile function.
RAD_IOP_STATUS_VALUES | Specifies the status values for the RAD_IOP asynchronous I/O functions.
RAD_IOP_OPENCALLBACK | points to a function that will be called when the async open file completes.
RAD_IOPGetFileHandleToIOPMemory | creates a file handle that can be used to read from IOP memory.
RAD_IOPGetFileHandleToSPUMemory | creates a file handle that can be used to read from SPU memory.
RAD_IOPGetFileHandleToLSN | creates a file handle that directly address a Logical Sector Number on a CD or DVD.
RAD_IOPQueueAsyncReadAtTop | queues an asynchronous read to be performed in the background at the highest priority.
RAD_IOP_ASYNC_READ_DATA | is a structure used to perform an asynchronous read.
RAD_IOP_ADDRESS_VALUES | Specifies the type of memory that you want to read into for the RAD_IOP asynchronous I/O functions.
RAD_IOP_READCALLBACK | points to a function that will be called when the async read completes.
RAD_IOPQueueAsyncReadAtBottom | queues an asynchronous read to be performed in the background at the lowest priority.
RAD_IOPGetIOStatus | returns the error code from a failed IO request.
RAD_IOPCancelAsyncOpen | cancels a previous asynchronous file open.
RAD_IOPCancelAsyncRead | cancels a previous asynchronous file read.
RAD_IOPCancelFileAsyncs | cancels all previous asynchronous file reads for a specified file handle.
RAD_IOPCancelGroupOfAsyncs | cancels all previous asynchronous file opens and reads for a specified group id.
RAD_IOPCancelAllAsyncs | cancels all previous asynchronous file opens and reads.
RAD_IOPCloseFile | closes a file handle opened with RAD_IOPQueueAsyncOpenFile.
RAD_IOPRegisterSoundCallback | registers a sound data structure to call your sound interrupt callback.
RAD_IOP_SOUND_DATA | is a structure used to control a sound interrupt callback.
RAD_IOP_SOUNDCALLBACK | points to a function that will be called periodically to fill a streaming sound buffer.
RAD_IOPStartSound | starts calling a previously registered sound callback.
RAD_IOPPauseSound | pauses a previously registered sound callback.
RAD_IOPUnregisterSoundCallback | unregisters a sound callback.
RAD_IOPRegisterTimerCallback | registers a timer structure to call your timer interrupt callback at a certain frequency.
RAD_IOP_TIMER_DATA | is a structure used to call a timer interrupt callback.
RAD_IOP_TIMERCALLBACK | points to a function that will be called periodically.
RAD_IOPStartTimer | starts calling a previously registered timer callback.
RAD_IOPPauseTimer | pauses a previously registered timer callback.
RAD_IOPUnregisterTimerCallback | unregisters a timer callback.
RAD_IOPHardwareVolumes | sets the sound core hardware volumes.
RADTimerRead | returns a rolling millisecond timer.
The RAD_IOP SPU Hardware Voice API for the Sony PS2
RAD_IOPSetSPUVoiceStartAddress | sets the address to play from for one or more SPU voices.
RAD_IOPSetSPUVoiceLoopAddress | sets the address to loop back to for one or more SPU voices.
RAD_IOPSetSPUVoiceVolume | sets the volume for one or more SPU voices.
RAD_IOPSetSPUVoicePitch | sets the pitch for one or more SPU voices.
RAD_IOPSetSPUVoiceADSR | sets the envelope for one or more SPU voices.
RAD_IOPSetSPUVoiceMixOnOff | sets the mix on-off routing for one or more SPU voices.
RAD_IOPSetSPUVoiceOnOff | starts or stops the playback of one or more SPU voices.
RAD_IOPQueueAsyncSPUVoiceState | asynchronously queries the state of an SPU voice.
RAD_IOP_SPU_VOICE_STATE | is a structure used with the RAD_IOPQueueAsyncSPUVoiceState function.
RAD_IOP_SPU_VOICE_STATE_CALLBACK | points to a function that will be called when the async query completes.
RAD_IOPQueueAsyncSPUGlobalState | asynchronously queries the state of the SPU cores.
RAD_IOP_SPU_GLOBAL_STATE | is a structure used with the RAD_IOPQueueAsyncSPUGlobalState function.
RAD_IOP_SPU_GLOBAL_STATE_CALLBACK | points to a function that will be called when the async query completes.
RAD_IOPFindNonPlayingVoiceMask | returns a bitmask that corresponds to a single non-playing voice.
Low-Level DOS Installation Services
AIL_install_DIG_driver_image | installs and initializes an MSS-compatible .DIG driver file for digital audio performance.
AIL_install_MDI_driver_image | Installs and initializes an MSS-compatible .MDI driver file for XMIDI music performance.
AIL_get_IO_environment | searches for and evaluates a DOS environment variable which contains I/O configuration data for a particular MSS driver.
AIL_read_INI | reads a standard MSS MDI.INI or DIG.INI file, parses it, and stores its contents in an application-specified AIL_INI structure.
AIL_INI | returns the contents of a MSS INI file.
AIL_install_driver | registers an MSS-compatible driver of any supported type with the MSS API, returning an AIL_DRIVER descriptor.
AIL_uninstall_driver | shuts down and unloads an MSS-compatible driver which was previously installed by AIL_install_driver above.
Low-Level DOS Support Services
AIL_set_real_vect | installs a real-mode handler real_ptr for interrupt vectnum.
AIL_set_USE16_ISR | creates a 16-bit protected-mode interrupt handler for interrupt vectnum, mapped to an existing bimodal interrupt handler in real-mode memory.
AIL_disable_interrupts | disables hardware interrupts (IRQs).
AIL_restore_interrupts | restores the hardware interrupt state effective prior to the last call to AIL_disable_interrupts (above).
AIL_switch_stack | allows a C or C++ module to change to a different stack whose size and location may be chosen by the programmer.
AIL_restore_stack | returns to the default stack which was in use prior to the last call to AIL_switch_stack.
AIL_get_real_vect | obtains the address of the current real-mode handler for interrupt vectnum.
AIL_call_driver | performs a call to an MSS-compatible sound driver in real-mode memory.
VDI_CALL | specifies the registers passed or returned from a real-mode driver call.
Preferences
MILES_PREFERENCES | describes the Miles Sound System Preferences.
Implementing Voice Chat
Voxware Voice Chat Codecs
Working with Voice Input
Accessing the Codecs Directly with the RIB Interface
Performing the Compression and Decompression
Integrating the Codecs with your Networking Architecture
Mixing the Client Sound Data on the Server
Implementation Details
Bandwidth Optimization and Channel Reliability Tips
Miles Sound System Tools Reference
Miles Sound Studio
Miles Sound Player
MIDIECHO for Windows - MIDI Data Receiver and Interpreter
MIDIECHO for MacOS - MIDI Data Receiver and Interpreter
MIDIECHO for DOS - MIDI Data Receiver and Interpreter
SETSOUND - MSS Sound Configuration Utility
GLIB - Extended MIDI (XMIDI) Global Timbre Librarian
CLAD - Creative Labs and Ad Lib (TM) Converter
MIDILOG - MIDI File Event Filter
MIDIREC- Standard MIDI File Recorder
WAVELIB - Wave Synthesizer Librarian
Extended MIDI Technical Reference
XMIDI Channel Mute (107)
XMIDI Callback Prefix (108)
XMIDI Sequence Branch (109)
XMIDI Channel Lock (110)
XMIDI Channel Lock Protect (111)
XMIDI Voice Protect (112)
XMIDI Timbre Protect (113)
XMIDI Patch Bank Select (114)
XMIDI Indirect Controller Prefix (115)
XMIDI For Loop Controller (116)
XMIDI Next-Break Loop Controller (117)
XMIDI Clear Beat-Bar Count (118)
XMIDI Callback Trigger (119)
XMIDI Sequence Branch Index (120)
Extended MIDI IFF (.XMI) Structure
Extended MIDI Global Timbre Library File Format
MSS Device Development Kit for DOS Sound Drivers
DOS Sound Driver Architecture
VDI_HDR | describes a DOS sound driver's Driver Header Table.
DOS Sound Driver Generic Initialization Interface
DDK Function: 300H Initialize Driver
DDK Function: 301H Get Driver Information
DDK Function: 302H Periodic Interrupt Service
DDK Function: 303H Parse Environment String
DDK Function: 304H Verify Device I/O Parameters
DDK Function: 305H Initialize Device
DDK Function: 306H Shut Down Device
DOS Digital Sound Driver Interface
DDK Function: 400H Get/Set Digital Hardware Volume
DDK Function: 401H Start Digital Playback Command
DDK Function: 402H Stop Digital Playback Request
DDK Function: 403H Start Digital Recording Command
DDK Function: 404H Stop Digital Recording Request
DDK Function: 405H Vendor-Specific Extensions
DOS XMIDI Sound Driver Interface
DDK Function: 500H Get/Set MIDI Hardware Volume
DDK Function: 501H Initialize Instrument Manager
DDK Function: 502H Transmit MIDI Data
DDK Function: 503H Install Timbre Set
DDK Function: 504H Get Timbre Status
DDK Function: 505H Protect/Unprotect Timbre
DDK Function: 506H Vendor-Specific Extensions
DDK Support Routines for Digital Sound Drivers
DDK Digital Function: INT66H_dispatch
DDK Digital Function: DIG_init
DDK Digital Function: DMAC_disable
DDK Digital Function: DMAC_enable
DDK Digital Function: DMAC_program
DDK Digital Function: ASC_val
DDK Digital Function: RAD_wait
DDK Digital Function: IRQ_hook
DDK Digital Function: IRQ_unhook
DDK Digital Function: IRQ_validate
DDK Digital Function: IRQ_acknowledge
DDK Support Routines for XMIDI Sound Drivers
DDK XMIDI Function: INT66H_dispatch
DDK XMIDI Function: MDI_init
DDK XMIDI Function: ASC_val
DDK XMIDI Function: RAD_wait
Change Log