SDL Mixer
SDL Mixer
29 July 2005
Jonathan Atkins
Copyright c 2002 Jonathan Atkins Permission is granted to distribute freely, or in a distribution of any kind. All distributions of this le must be in an unaltered state, except for corrections. The latest copy of this document can be found at http://jcatki.no-ip.org/SDL_mixer
Table of Contents
1 2 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 Getting Started . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.1 2.2 Includes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 Compiling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
3 4
Conicts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
4.1 General. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 4.1.1 Mix Linked Version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 4.1.2 Mix OpenAudio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 4.1.3 Mix CloseAudio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 4.1.4 Mix SetError . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 4.1.5 Mix GetError . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 4.1.6 Mix QuerySpec . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 4.2 Samples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 4.2.1 Mix LoadWAV . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 4.2.2 Mix LoadWAV RW . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 4.2.3 Mix QuickLoad WAV . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 4.2.4 Mix QuickLoad RAW . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 4.2.5 Mix VolumeChunk. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 4.2.6 Mix FreeChunk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 4.3 Channels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 4.3.1 Mix AllocateChannels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 4.3.2 Mix Volume . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 4.3.3 Mix PlayChannel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 4.3.4 Mix PlayChannelTimed . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 4.3.5 Mix FadeInChannel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 4.3.6 Mix FadeInChannelTimed . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 4.3.7 Mix Pause . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 4.3.8 Mix Resume . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 4.3.9 Mix HaltChannel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 4.3.10 Mix ExpireChannel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 4.3.11 Mix FadeOutChannel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 4.3.12 Mix ChannelFinished . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 4.3.13 Mix Playing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36 4.3.14 Mix Paused . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 4.3.15 Mix FadingChannel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 4.3.16 Mix GetChunk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 4.4 Groups . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 4.4.1 Mix ReserveChannels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
ii 4.4.2 Mix GroupChannel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.4.3 Mix GroupChannels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.4.4 Mix GroupCount . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.4.5 Mix GroupAvailable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.4.6 Mix GroupOldest . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.4.7 Mix GroupNewer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.4.8 Mix FadeOutGroup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.4.9 Mix HaltGroup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.5 Music . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.5.1 Mix LoadMUS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.5.2 Mix FreeMusic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.5.3 Mix PlayMusic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.5.4 Mix FadeInMusic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.5.5 Mix FadeInMusicPos. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.5.6 Mix HookMusic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.5.7 Mix VolumeMusic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.5.8 Mix PauseMusic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.5.9 Mix ResumeMusic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.5.10 Mix RewindMusic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.5.11 Mix SetMusicPosition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.5.12 Mix SetMusicCMD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.5.13 Mix HaltMusic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.5.14 Mix FadeOutMusic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.5.15 Mix HookMusicFinished . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.5.16 Mix GetMusicType . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.5.17 Mix PlayingMusic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.5.18 Mix PausedMusic. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.5.19 Mix FadingMusic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.5.20 Mix GetMusicHookData . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.6 Eects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.6.1 Mix RegisterEect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.6.2 Mix UnregisterEect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.6.3 Mix UnregisterAllEects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.6.4 Mix SetPostMix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.6.5 Mix SetPanning . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.6.6 Mix SetDistance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.6.7 Mix SetPosition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.6.8 Mix SetReverseStereo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
5.1 5.2 5.3 5.4 5.5 5.6 Mix Mix Mix Mix Mix Mix Chunk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Music . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . MusicType . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Fading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EectFunc t. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EectDone t . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 82 83 84 85 86
Denes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
iii
Glossary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
Chapter 1: Overview
1 Overview
A Little Bit About Me I am currently, as I write this document, a programmer for Raytheon. There I do all sorts of communications, network, GUI, and other general programming tasks in C/C++ on the Solaris and sometimes Linux Operating Systems. I have been programming sound code in my free time for only a little while now. Sound is an integral part to any game. The human senses are mostly starved during video game play. theres only some tactile feedback on some controlers, and of course the eyes are in use but only for about 30% of their viewing area. So to add more we do need sound to help the game player feel more in the action, and to set certain moods as the game progresses. Sound ends up accounting for perhaps 50% or more of a gamers experience. Music and sound eects are all integral parts of the gaming experience. While this document doesnt explain how to get music and samples to use, it will explain how to use them with SDL mixer. Feel free to contact me: [email protected] I am also usually on IRC at irc.freenode.net in the #SDL channel as LIM
Chapter 1: Overview
SDL mixer 1.2 The latest version of this library is available from: SDL mixer Homepage Due to popular demand, here is a simple multi-channel audio mixer. It supports 8 channels of 16 bit stereo audio, plus a single channel of music, mixed by the popular MikMod MOD, Timidity MIDI and SMPEG MP3 libraries. See the header le SDL mixer.h and the examples playwave.c and playmus.c for documentation on this mixer library. The mixer can currently load Microsoft WAVE les and Creative Labs VOC les as audio samples, and can load MIDI les via Timidity and the following music formats via MikMod: .MOD .S3M .IT .XM. It can load Ogg Vorbis streams as music if built with the Ogg Vorbis libraries, and nally it can load MP3 music using the SMPEG library. The process of mixing MIDI les to wave output is very CPU intensive, so if playing regular WAVE les sound great, but playing MIDI les sound choppy, try using 8-bit audio, mono audio, or lower frequencies. To play MIDI les, youll need to get a complete set of GUS patches from: Timidity GUS Patches and unpack them in /usr/local/lib under UNIX, and C:\ under Win32. This library is available under the GNU Library General Public License, see the le "COPYING" for details.
2 Getting Started
This assumes you have gotten SDL mixer and installed it on your system. SDL mixer has an INSTALL document in the source distribution to help you get it compiled and installed. Generally, installation consists of:
SDL mixer supports playing music and sound samples from the following formats: - WAVE/RIFF (.wav) - AIFF (.ai) - VOC (.voc) - MOD (.mod .xm .s3m .669 .it .med and more) using included mikmod - MIDI (.mid) using timidity or native midi hardware - OggVorbis (.ogg) requiring ogg/vorbis libraries on system - MP3 (.mp3) requiring SMPEG library on system - also any command-line player, which is not mixed by SDL mixer... You may also want to look at some demonstration code which may be downloaded from: http://jcatki.no-ip.org/SDL_mixer/
2.1 Includes
To use SDL mixer functions in a C/C++ source code le, you must use the SDL mixer.h include le:
#include "SDL_mixer.h"
2.2 Compiling
To link with SDL mixer you should use sdl-cong to get the required SDL compilation options. After that, compiling with SDL mixer is quite easy. Note: Some systems may not have the SDL mixer library and include le in the same place as the SDL library and includes are located, in that case you will need to add more -I and -L paths to these command lines.
Simple Example for compiling an object le: cc -c sdl-config --cflags mysource.c Simple Example for compiling an object le: cc -o myprogram mysource.o sdl-config --libs -lSDL_mixer Now myprogram is ready to run.
Chapter 3: Conicts
3 Conicts
When using SDL mixer functions you need to avoid the following functions from SDL: SDL_OpenAudio Use Mix_OpenAudio instead. SDL_CloseAudio Use Mix_CloseAudio instead. SDL_PauseAudio Use Mix_Pause(-1) and Mix_PauseMusic instead, to pause. Use Mix_Resume(-1) and Mix_ResumeMusic instead, to unpause. SDL_LockAudio This is just not needed since SDL mixer handles this for you. Using it may cause problems as well. SDL_UnlockAudio This is just not needed since SDL mixer handles this for you. Using it may cause problems as well. You may call the following functions freely: SDL_AudioDriverName This will still work as usual. SDL_GetAudioStatus This will still work, though it will likely return SDL AUDIO PLAYING even though SDL mixer is just playing silence. It is also a BAD idea to call SDL mixer and SDL audio functions from a callback. Callbacks include Eects functions and other SDL mixer audio hooks.
Chapter 4: Functions
4 Functions
These are the functions in the SDL mixer API.
Chapter 4: Functions
4.1 General
These functions are useful, as they are the only/best ways to work with SDL mixer.
Chapter 4: Functions
SDL_version compile_version, *link_version; MIX_VERSION(&compile_version); printf("compiled with SDL_mixer version: %d.%d.%d\n", compile_version.major, compile_version.minor, compile_version.patch); link_version=Mix_Linked_Version(); printf("running with SDL_mixer version: %d.%d.%d\n", link_version->major, link_version->minor, link_version->patch);
See Also: Section 4.1.2 [Mix OpenAudio], page 10, Section 4.1.6 [Mix QuerySpec], page 15
Chapter 4: Functions
10
Initialize the mixer API. This must be called before using other functions in this library. SDL must be initialized with SDL INIT AUDIO before this call. frequency would be 44100 for 44.1KHz, which is CD audio rate. Most games use 22050, because 44100 requires too much CPU power on older computers. chunksize is the size of each mixed sample. The smaller this is the more your hooks will be called. If make this too small on a slow system, sound may skip. If made to large, sound eects will lag behind the action more. You want a happy medium for your target computer. You also may make this 4096, or larger, if you are just playing music. MIX CHANNELS(8) mixing channels will be allocated by default. You may call this function multiple times, however you will have to call Mix CloseAudio just as many times for the device to actually close. The format will not changed on subsequent calls. So you will have to close all the way before trying to open with dierent format parameters. format is based on SDL audio support, see SDL audio.h. Here are the values listed there: AUDIO U8 Unsigned 8-bit samples AUDIO S8 Signed 8-bit samples AUDIO U16LSB Unsigned 16-bit samples, in little-endian byte order AUDIO S16LSB Signed 16-bit samples, in little-endian byte order AUDIO U16MSB Unsigned 16-bit samples, in big-endian byte order AUDIO S16MSB Signed 16-bit samples, in big-endian byte order
Chapter 4: Functions
11
AUDIO U16 same as AUDIO U16LSB (for backwards compatability probably) AUDIO S16 same as AUDIO S16LSB (for backwards compatability probably) AUDIO U16SYS Unsigned 16-bit samples, in system byte order AUDIO S16SYS Signed 16-bit samples, in system byte order
MIX DEFAULT FORMAT is the same as AUDIO S16SYS. Returns: 0 on success, -1 on errors
// start SDL with audio support if(SDL_Init(SDL_INIT_AUDIO)==-1) { printf("SDL_Init: %s\n", SDL_GetError()); exit(1); } // open 44.1KHz, signed 16bit, system byte order, // stereo audio, using 1024 byte chunks if(Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 1024)==-1) { printf("Mix_OpenAudio: %s\n", Mix_GetError()); exit(2); }
See Also: Section 4.1.3 [Mix CloseAudio], page 12, Section 4.1.6 [Mix QuerySpec], page 15, Section 4.3.1 [Mix AllocateChannels], page 24
Chapter 4: Functions
12
See Also: Section 4.1.2 [Mix OpenAudio], page 10, Section 4.1.6 [Mix QuerySpec], page 15
Chapter 4: Functions
13
Chapter 4: Functions
14
Chapter 4: Functions
15
Get the actual audio format in use by the opened audio device. This may or may not match the parameters you passed to Mix OpenAudio. Returns: 0 on error. If the device was open the number of times it was opened will be returned. The values of the arguments variables are not set on an error.
// get and print the audio format in use int numtimesopened, frequency, channels; Uint16 format; numtimesopened=Mix_QuerySpec(&frequency, &format, &channels); if(!numtimesopened) { printf("Mix_QuerySpec: %s\n",Mix_GetError()); } else { char *format_str="Unknown"; switch(format) { case AUDIO_U8: format_str="U8"; break; case AUDIO_S8: format_str="S8"; break; case AUDIO_U16LSB: format_str="U16LSB"; break; case AUDIO_S16LSB: format_str="S16LSB"; break; case AUDIO_U16MSB: format_str="U16MSB"; break; case AUDIO_S16MSB: format_str="S16MSB"; break; } printf("opened=%d times frequency=%dHz format=%s channels=%d", numtimesopened, frequency, format_str, channels); }
Chapter 4: Functions
16
4.2 Samples
These functions work with Mix_Chunk samples.
Chapter 4: Functions
17
Load le for use as a sample. This is actually Mix_LoadWAV_RW(SDL_RWFromFile(file, "rb"), 1). This can load WAVE, AIFF, RIFF, OGG, and VOC les. Note: You must call SDL OpenAudio before this. It must know the output characteristics so it can convert the sample for playback, it does this conversion at load time. Returns: a pointer to the sample as a Mix_Chunk. NULL is returned on errors.
// load sample.wav in to sample Mix_Chunk *sample; sample=Mix_LoadWAV("sample.wav"); if(!sample) { printf("Mix_LoadWAV: %s\n", Mix_GetError()); // handle error }
See Also: Section 4.2.2 [Mix LoadWAV RW], page 18, Section 4.2.3 [Mix QuickLoad WAV], page 19, Section 4.2.6 [Mix FreeChunk], page 22
Chapter 4: Functions
18
Load src for use as a sample. This can load WAVE, AIFF, RIFF, OGG, and VOC formats. Using SDL_RWops is not covered here, but they enable you to load from almost any source. Note: You must call SDL OpenAudio before this. It must know the output characteristics so it can convert the sample for playback, it does this conversion at load time. Returns: a pointer to the sample as a Mix_Chunk. NULL is returned on errors.
// load sample.wav in to sample Mix_Chunk *sample; sample=Mix_LoadWAV_RW(SDL_RWFromFile("sample.wav", "rb"), 1); if(!sample) { printf("Mix_LoadWAV_RW: %s\n", Mix_GetError()); // handle error }
See Also: Section 4.2.1 [Mix LoadWAV], page 17, Section 4.2.3 [Mix QuickLoad WAV], page 19, Section 4.2.6 [Mix FreeChunk], page 22
Chapter 4: Functions
19
Load mem as a WAVE/RIFF le into a new sample. The WAVE in mem must be already in the output format. It would be better to use Mix_LoadWAV_RW if you arent sure. Note: This function does very little checking. If the format mismatches the output format, or if the buer is not a WAVE, it will not return an error. This is probably a dangerous function to use. Returns: a pointer to the sample as a Mix_Chunk. NULL is returned on errors.
// quick-load a wave from memory // Uint8 *wave; // I assume you have the wave loaded raw, // or compiled in the program... Mix_Chunk *wave_chunk; if(!(wave_chunk=Mix_QuickLoad_WAV(wave))) { printf("Mix_QuickLoad_WAV: %s\n", Mix_GetError()); // handle error }
See Also: Section 4.2.1 [Mix LoadWAV], page 17, Section 4.2.4 [Mix QuickLoad RAW], page 20, Section 4.2.6 [Mix FreeChunk], page 22
Chapter 4: Functions
20
Load mem as a raw sample. The data in mem must be already in the output format. If you arent sure what you are doing, this is not a good function for you! Note: This function does very little checking. If the format mismatches the output format it will not return an error. This is probably a dangerous function to use. Returns: a pointer to the sample as a Mix_Chunk. NULL is returned on errors, such as when out of memory.
// quick-load a raw sample from memory // Uint8 *raw; // I assume you have the raw data here, // or compiled in the program... Mix_Chunk *raw_chunk; if(!(raw_chunk=Mix_QuickLoad_RAW(raw))) { printf("Mix_QuickLoad_RAW: %s\n", Mix_GetError()); // handle error }
See Also: Section 4.2.1 [Mix LoadWAV], page 17, Section 4.2.3 [Mix QuickLoad WAV], page 19, Section 4.2.6 [Mix FreeChunk], page 22
Chapter 4: Functions
21
Set chunk->volume to volume. The volume setting will take eect when the chunk is used on a channel, being mixed into the output. Returns: previous chunk->volume setting. if you passed a negative value for volume then this volume is still the current volume for the chunk.
// set the samples volume to 1/2 // Mix_Chunk *sample; int previous_volume; previous_volume=Mix_VolumeChunk(sample, MIX_MAX_VOLUME/2); printf("previous_volume: %d\n", previous_volume);
Chapter 4: Functions
22
Free the memory used in chunk, and free chunk itself as well. Do not use chunk after this without loading a new sample to it. Note: Its a bad idea to free a chunk that is still being played...
See Also: Section 4.2.1 [Mix LoadWAV], page 17, Section 4.2.2 [Mix LoadWAV RW], page 18, Section 4.2.3 [Mix QuickLoad WAV], page 19,
Chapter 4: Functions
23
4.3 Channels
These functions work with sound eect mixer channels. Music is not aected by these functions.
Chapter 4: Functions
24
Chapter 4: Functions
25
Set the volume for any allocated channel. If channel is -1 then all channels at are set at once. The volume is applied during the nal mix, along with the sample volume. So setting this volume to 64 will halve the output of all samples played on the specied channel. All channels default to a volume of 128, which is the max. Newly allocated channels will have the max volume set, so setting all channels volumes does not aect subsequent channel allocations. Returns: current volume of the channel. If channel is -1, the average volume is returned.
// set channel 1 to half volume Mix_Volume(1,MIX_MAX_VOLUME/2); // print the average volume printf("Average volume is %d\n",Mix_Volume(-1,-1));
See Also: Section 4.2.5 [Mix VolumeChunk], page 21, Section 4.5.7 [Mix VolumeMusic], page 57
Chapter 4: Functions
26
Play chunk on channel, or if channel is -1, pick the rst free unreserved channel. The sample will play for loops+1 number of times, unless stopped by halt, or fade out, or setting a new expiration time of less time than it would have originally taken to play the loops, or closing the mixer. Note: this just calls Mix_PlayChannelTimed() with ticks set to -1. Returns: the channel the sample is played on. On any errors, -1 is returned.
// play sample on first free unreserved channel // play it exactly once through // Mix_Chunk *sample; //previously loaded if(Mix_PlayChannel(-1, sample, 0)==-1) { printf("Mix_PlayChannel: %s\n",Mix_GetError()); // may be critical error, or maybe just no channels were free. // you could allocated another channel in that case... }
See Also: Section 4.3.4 [Mix PlayChannelTimed], page 27, Section 4.3.5 [Mix FadeInChannel], page 28, Section 4.3.9 [Mix HaltChannel], page 32, Section 4.3.10 [Mix ExpireChannel], page 33, Section 4.4.1 [Mix ReserveChannels], page 41
Chapter 4: Functions
27
If the sample is long enough and has enough loops then the sample will stop after ticks milliseconds. Otherwise this function is the same as Section 4.3.3 [Mix PlayChannel], page 26. Returns: the channel the sample is played on. On any errors, -1 is returned.
// play sample on first free unreserved channel // play it for half a second // Mix_Chunk *sample; //previously loaded if(Mix_PlayChannelTimed(-1, sample, -1 , 500)==-1) { printf("Mix_PlayChannel: %s\n",Mix_GetError()); // may be critical error, or maybe just no channels were free. // you could allocated another channel in that case... }
See Also: Section 4.3.3 [Mix PlayChannel], page 26, Section 4.3.6 [Mix FadeInChannelTimed], page 29, Section 4.3.11 [Mix FadeOutChannel], page 34, Section 4.4.1 [Mix ReserveChannels], page 41
Chapter 4: Functions
28
Play chunk on channel, or if channel is -1, pick the rst free unreserved channel. The channel volume starts at 0 and fades up to full volume over ms milliseconds of time. The sample may end before the fade-in is complete if it is too short or doesnt have enough loops. The sample will play for loops+1 number of times, unless stopped by halt, or fade out, or setting a new expiration time of less time than it would have originally taken to play the loops, or closing the mixer. Note: this just calls Mix_FadeInChannelTimed() with ticks set to -1. Returns: the channel the sample is played on. On any errors, -1 is returned.
// play sample on first free unreserved channel // play it exactly 3 times through // fade in over one second // Mix_Chunk *sample; //previously loaded if(Mix_FadeInChannel(-1, sample, 2, 1000)==-1) { printf("Mix_FadeInChannel: %s\n",Mix_GetError()); // may be critical error, or maybe just no channels were free. // you could allocated another channel in that case... }
See Also: Section 4.3.3 [Mix PlayChannel], page 26, Section 4.3.6 [Mix FadeInChannelTimed], page 29, Section 4.3.15 [Mix FadingChannel], page 38, Section 4.3.11 [Mix FadeOutChannel], page 34, Section 4.4.1 [Mix ReserveChannels], page 41
Chapter 4: Functions
29
If the sample is long enough and has enough loops then the sample will stop after ticks milliseconds. Otherwise this function is the same as Section 4.3.5 [Mix FadeInChannel], page 28. Returns: the channel the sample is played on. On any errors, -1 is returned.
// play sample on first free unreserved channel // play it for half a second // Mix_Chunk *sample; //previously loaded if(Mix_PlayChannelTimed(-1, sample, -1 , 500)==-1) { printf("Mix_PlayChannel: %s\n",Mix_GetError()); // may be critical error, or maybe just no channels were free. // you could allocated another channel in that case... }
See Also: Section 4.3.4 [Mix PlayChannelTimed], page 27, Section 4.3.5 [Mix FadeInChannel], page 28, Section 4.3.15 [Mix FadingChannel], page 38, Section 4.3.9 [Mix HaltChannel], page 32, Section 4.3.10 [Mix ExpireChannel], page 33, Section 4.4.1 [Mix ReserveChannels], page 41
Chapter 4: Functions
30
Pause channel, or all playing channels if -1 is passed in. You may still halt a paused channel. Note: Only channels which are actively playing will be paused.
See Also: Section 4.3.8 [Mix Resume], page 31, Section 4.3.14 [Mix Paused], page 37, Section 4.3.9 [Mix HaltChannel], page 32
Chapter 4: Functions
31
Unpause channel, or all playing and paused channels if -1 is passed in. // resume playback on all previously active channels Mix_Resume(-1);
See Also: Section 4.3.7 [Mix Pause], page 30, Section 4.3.14 [Mix Paused], page 37
Chapter 4: Functions
32
Halt channel playback, or all channels if -1 is passed in. Any callback set by Mix_ChannelFinished will be called. Returns: always returns zero. (kinda silly)
See Also: Section 4.3.10 [Mix ExpireChannel], page 33, Section 4.3.11 [Mix FadeOutChannel], page 34, Section 4.3.12 [Mix ChannelFinished], page 35
Chapter 4: Functions
33
Halt channel playback, or all channels if -1 is passed in, after ticks milliseconds. Any callback set by Mix_ChannelFinished will be called when the channel expires. Returns: Number of channels set to expire. Whether or not they are active.
See Also: Section 4.3.9 [Mix HaltChannel], page 32, Section 4.3.11 [Mix FadeOutChannel], page 34, Section 4.3.12 [Mix ChannelFinished], page 35
Chapter 4: Functions
34
Gradually fade out which channel over ms milliseconds starting from now. The channel will be halted after the fade out is completed. Only channels that are playing are set to fade out, including paused channels. Any callback set by Mix_ChannelFinished will be called when the channel nishes fading out. Returns: The number of channels set to fade out.
// fade out all channels to finish 3 seconds from now printf("starting fade out of %d channels\n", Mix_FadeOutChannel(-1, 3000));
See Also: Section 4.3.5 [Mix FadeInChannel], page 28, Section 4.3.6 [Mix FadeInChannelTimed], page 29, Section 4.3.15 [Mix FadingChannel], page 38, Section 4.3.12 [Mix ChannelFinished], page 35
Chapter 4: Functions
35
// make a channelDone function void channelDone(int channel) { printf("channel %d finished playing.\n", channel); } ... // set the callback for when a channel stops playing Mix_ChannelFinished(channelDone);
See Also: Section 4.3.9 [Mix HaltChannel], page 32, Section 4.3.10 [Mix ExpireChannel], page 33
Chapter 4: Functions
36
Tells you if channel is playing, or not. Note: Does not check if the channel has been paused. Returns: Zero if the channel is not playing. Otherwise if you passed in -1, the number of channels playing is returned. If you passed in a specic channel, then 1 is returned if it is playing.
// check how many channels are playing samples printf("%d channels are playing\n", Mix_Playing(-1));
See Also: Section 4.3.14 [Mix Paused], page 37, Section 5.4 [Mix Fading], page 84, Section 4.3.3 [Mix PlayChannel], page 26, Section 4.3.7 [Mix Pause], page 30,
Chapter 4: Functions
37
Tells you if channel is paused, or not. Note: Does not check if the channel has been halted after it was paused, which may seem a little weird. Returns: Zero if the channel is not paused. Otherwise if you passed in -1, the number of paused channels is returned. If you passed in a specic channel, then 1 is returned if it is paused.
// check the pause status on all channels printf("%d channels are paused\n", Mix_Paused(-1));
See Also: Section 4.3.13 [Mix Playing], page 36, Section 4.3.7 [Mix Pause], page 30, Section 4.3.8 [Mix Resume], page 31
Chapter 4: Functions
38
Tells you if which channel is fading in, out, or not. Does not tell you if the channel is playing anything, or paused, so youd need to test that separately. Returns: the fading status. Never returns an error. // check the fade status on channel 0 switch(Mix_FadingChannel(0)) { case MIX_NO_FADING: printf("Not fading.\n"); break; case MIX_FADING_OUT: printf("Fading out.\n"); break; case MIX_FADING_IN: printf("Fading in.\n"); break; }
See Also: Section 5.4 [Mix Fading], page 84, Section 4.3.13 [Mix Playing], page 36, Section 4.3.14 [Mix Paused], page 37, Section 4.3.5 [Mix FadeInChannel], page 28, Section 4.3.6 [Mix FadeInChannelTimed], page 29, Section 4.3.11 [Mix FadeOutChannel], page 34
Chapter 4: Functions
39
Get the most recent sample chunk pointer played on channel. This pointer may be currently playing, or just the last used. Note: The actual chunk may have been freed, so this pointer may not be valid anymore. Returns: Pointer to the Mix Chunk. NULL is returned if the channel is not allocated, or if the channel has not played any samples yet.
// get the last chunk used by channel 0 printf("Mix_Chunk* last in use on channel 0 was: %08p\n", Mix_GetChunk(0));
See Also: Section 5.1 [Mix Chunk], page 81, Section 4.3.13 [Mix Playing], page 36
Chapter 4: Functions
40
4.4 Groups
These functions work with groupings of mixer channels. The default group tag number of -1, which refers to ALL channels.
Chapter 4: Functions
41
Reserve num channels from being used when playing samples when passing in -1 as a channel number to playback functions. The channels are reserved starting from channel 0 to num1. Passing in zero will unreserve all channels. Normally SDL mixer starts without any channels reserved. The following functions are aected by this setting: Section 4.3.3 [Mix PlayChannel], page 26 Section 4.3.4 [Mix PlayChannelTimed], page 27 Section 4.3.5 [Mix FadeInChannel], page 28 Section 4.3.6 [Mix FadeInChannelTimed], page 29 Returns: The number of channels reserved. Never fails, but may return less channels than you ask for, depending on the number of channels previously allocated.
// reserve the first 8 mixing channels int reserved_count; reserved_count=Mix_ReserveChannels(8); if(reserved_count!=8) { printf("reserved %d channels from default mixing.\n",reserved_count); printf("8 channels were not reserved!\n"); // this might be a critical error... }
Chapter 4: Functions
42
Add which channel to group tag, or reset its group to the default group tag (-1). Returns: True(1) on success. False(0) is returned when the channel specied is invalid.
// add channel 0 to group 1 if(!Mix_GroupChannel(0,1)) { // bad channel, apparently channel 1 isnt allocated }
See Also: Section 4.4.3 [Mix GroupChannels], page 43, Section 4.3.1 [Mix AllocateChannels], page 24
Chapter 4: Functions
43
Add channels starting at from up through to to group tag, or reset its group to the default group tag (-1). Returns: The number of tagged channels on success. If that number is less than to-from+1 then some channels were no tagged because they didnt exist.
// add channels 0 through 7 to group 1 if(Mix_GroupChannels(0,7,1)!=8) { // some bad channels, apparently some channels arent allocated }
See Also: Section 4.4.2 [Mix GroupChannel], page 42, Section 4.3.1 [Mix AllocateChannels], page 24
Chapter 4: Functions
44
Count the number of channels in group tag. Returns: The number of channels found in the group. This function never fails.
// count the number of channels in group 1 printf("There are %d channels in group 1\n", Mix_GroupCount(1));
See Also: Section 4.4.2 [Mix GroupChannel], page 42, Section 4.4.3 [Mix GroupChannels], page 43
Chapter 4: Functions
45
Find the rst available (not playing) channel in group tag. Returns: The channel found on success. -1 is returned when no channels in the group are available.
// find the first available channel in group 1 int channel; channel=Mix_GroupAvailable(1); if (channel==-1) { // no channel available... // perhaps search for oldest or newest channel in use... }
See Also: Section 4.4.6 [Mix GroupOldest], page 46, Section 4.4.7 [Mix GroupNewer], page 47, Section 4.4.2 [Mix GroupChannel], page 42, Section 4.4.3 [Mix GroupChannels], page 43
Chapter 4: Functions
46
Find the oldest actively playing channel in group tag. Returns: The channel found on success. -1 is returned when no channels in the group are playing or the group is empty.
// find the oldest playing channel in group 1 int channel; channel=Mix_GroupOldest(1); if (channel==-1) { // no channel playing or allocated... // perhaps just search for an available channel... }
See Also: Section 4.4.7 [Mix GroupNewer], page 47, Section 4.4.5 [Mix GroupAvailable], page 45, Section 4.4.2 [Mix GroupChannel], page 42, Section 4.4.3 [Mix GroupChannels], page 43
Chapter 4: Functions
47
Find the newest, most recently started, actively playing channel in group tag. Returns: The channel found on success. -1 is returned when no channels in the group are playing or the group is empty.
// find the newest playing channel in group 1 int channel; channel=Mix_GroupNewer(1); if (channel==-1) { // no channel playing or allocated... // perhaps just search for an available channel... }
See Also: Section 4.4.6 [Mix GroupOldest], page 46, Section 4.4.5 [Mix GroupAvailable], page 45, Section 4.4.2 [Mix GroupChannel], page 42, Section 4.4.3 [Mix GroupChannels], page 43
Chapter 4: Functions
48
ms
Gradually fade out channels in group tag over ms milliseconds starting from now. The channels will be halted after the fade out is completed. Only channels that are playing are set to fade out, including paused channels. Any callback set by Mix_ChannelFinished will be called when each channel nishes fading out. Returns: The number of channels set to fade out.
// fade out all channels in group 1 to finish 3 seconds from now printf("starting fade out of %d channels\n", Mix_FadeOutGroup(1, 3000));
See Also: Section 4.4.9 [Mix HaltGroup], page 49, Section 4.3.11 [Mix FadeOutChannel], page 34, Section 4.3.15 [Mix FadingChannel], page 38, Section 4.3.12 [Mix ChannelFinished], page 35
Chapter 4: Functions
49
Halt playback on all channels in group tag. Any callback set by Mix_ChannelFinished will be called once for each channel that stops. Returns: always returns zero. (more silly than Mix HaltChannel)
See Also: Section 4.4.8 [Mix FadeOutGroup], page 48, Section 4.3.9 [Mix HaltChannel], page 32, Section 4.3.12 [Mix ChannelFinished], page 35
Chapter 4: Functions
50
4.5 Music
These functions work with music. Music is not played on a normal mixer channel. Music is therefore manipulated separately, except in post-processing hooks.
Chapter 4: Functions
51
Load music le to use. This can load WAVE, MOD, MIDI, OGG, MP3, and any le that you use a command to play with. If you are using an external command to play the music, you must call Mix_SetMusicCMD before this, otherwise the internal players will be used. Alternatively, if you have set an external command up and dont want to use it, you must call Mix_SetMusicCMD(NULL) to use the built-in players again. Returns: A pointer to a Mix Music. NULL is returned on errors.
// load the MP3 file "music.mp3" to play as music Mix_Music *music; music=Mix_LoadMUS("music.mp3"); if(!music) { printf("Mix_LoadMUS(\"music.mp3\"): %s\n", Mix_GetError()); // this might be a critical error... }
See Also: Section 5.2 [Mix Music], page 82, Section 4.5.12 [Mix SetMusicCMD], page 62, Section 4.5.3 [Mix PlayMusic], page 53, Section 4.5.4 [Mix FadeInMusic], page 54, Section 4.5.5 [Mix FadeInMusicPos], page 55
Chapter 4: Functions
52
Free the loaded music. If music is playing it will be halted. If music is fading out, then this function will wait (blocking) until the fade out is complete.
Chapter 4: Functions
53
Play the loaded music loop times through from start to nish. The previous music will be halted, or if fading out it waits (blocking) for that to nish. Returns: 0 on success, or -1 on errors.
// play music forever // Mix_Music *music; // I assume this has been loaded already if(Mix_PlayMusic(music, -1)==-1) { printf("Mix_PlayMusic: %s\n", Mix_GetError()); // well, theres no music, but most games dont break without music... }
Chapter 4: Functions
54
ms
Fade in over ms milliseconds of time, the loaded music, playing it loop times through from start to nish. The fade in eect only applies to the rst loop. Any previous music will be halted, or if it is fading out it will wait (blocking) for the fade to complete. This function is the same as Mix_FadeInMusicPos(music, loops, ms, 0). Returns: 0 on success, or -1 on errors.
// play music forever, fading in over 2 seconds // Mix_Music *music; // I assume this has been loaded already if(Mix_FadeInMusic(music, -1, 2000)==-1) { printf("Mix_FadeInMusic: %s\n", Mix_GetError()); // well, theres no music, but most games dont break without music... }
See Also: Section 4.5.3 [Mix PlayMusic], page 53, Section 4.5.5 [Mix FadeInMusicPos], page 55
Chapter 4: Functions
55
ms position
Fade in over ms milliseconds of time, the loaded music, playing it loop times through from start to nish. The fade in eect only applies to the rst loop. The rst time the music is played, it posistion will be set to posistion, which means dierent things for dierent types of music les, see Mix_SetMusicPosition for more info on that. Any previous music will be halted, or if it is fading out it will wait (blocking) for the fade to complete. Returns: 0 on success, or -1 on errors.
// play music forever, fading in over 2 seconds // Mix_Music *music; // I assume this has been loaded already if(Mix_FadeInMusicPos(music, -1, 2000)==-1) { printf("Mix_FadeInMusic: %s\n", Mix_GetError()); // well, theres no music, but most games dont break without music... }
See Also: Section 4.5.3 [Mix PlayMusic], page 53, Section 4.5.4 [Mix FadeInMusic], page 54, Section 4.5.11 [Mix SetMusicPosition], page 61
Chapter 4: Functions
56
arg
This sets up a custom music player function. The function will be called with arg passed into the udata parameter when the mix func is called. The stream parameter passes in the audio stream buer to be lled with len bytes of music. The music player will then be called automatically when the mixer needs it. Music playing will start as soon as this is called. All the music playing and stopping functions have no eect on music after this. Pause and resume will work. Using a custom music player and the internal music player is not possible, the custom music player takes priority. To stop the custom music player call Mix_HookMusic(NULL, NULL). NOTE: NEVER call SDL Mixer functions, nor SDL_LockAudio, from a callback function.
// make a music play function // it expects udata to be a pointer to an int void myMusicPlayer(void *udata, Uint8 *stream, int len) { int i, pos=*(int*)udata; // fill buffer with...uh...music... for(i=0; i<len; i++) stream[i]=(i+pos)&ff; // set udata for next time pos+=len; *(int*)udata=pos; } ... // use myMusicPlayer for playing...uh...music int music_pos=0; Mix_HookMusic(myMusicPlayer, &music_pos);
See Also: Section 4.5.12 [Mix SetMusicCMD], page 62, Section 4.5.20 [Mix GetMusicHookData], page 70
Chapter 4: Functions
57
Set the volume to volume, if it is 0 or greater, and return the previous volume setting. Setting the volume during a fade will not work, the faders use this function to perform their eect! Setting volume while using an external music player set by Mix_SetMusicCMD will have no eect, and Mix_GetError will show the reason why not. Returns: The previous volume setting.
// set the music volume to 1/2 maximum, and then check it printf("volume was : %d\n", Mix_VolumeMusic(MIX_MAX_VOLUME/2)); printf("volume is now : %d\n", Mix_VolumeMusic(-1));
See Also: Section 4.5.4 [Mix FadeInMusic], page 54, Section 4.5.14 [Mix FadeOutMusic], page 64, Section 4.5.12 [Mix SetMusicCMD], page 62
Chapter 4: Functions
58
See Also: Section 4.5.9 [Mix ResumeMusic], page 59, Section 4.5.18 [Mix PausedMusic], page 68, Section 4.5.13 [Mix HaltMusic], page 63
Chapter 4: Functions
59
See Also: Section 4.5.8 [Mix PauseMusic], page 58, Section 4.5.18 [Mix PausedMusic], page 68
Chapter 4: Functions
60
Chapter 4: Functions
61
Set the position of the currently playing music. The position takes dierent meanings for dierent music sources. It only works on the music sources listed below. MOD OGG MP3 The double is cast to Uint16 and used for a pattern number in the module. Passing zero is similar to rewinding the song. Jumps to position seconds from the beginning of the song. Jumps to position seconds from the current position in the stream. So you may want to call Mix_RewindMusic before this. Does not go in reverse...negative values do nothing.
// skip one minute into the song, from the start // this assumes you are playing an MP3 Mix_RewindMusic(); if(Mix_SetMusicPosition(60.0)==-1) { printf("Mix_SetMusicPosition: %s\n", Mix_GetError()); }
Chapter 4: Functions
62
Setup a command line music player to use to play music. Any music playing will be halted. The music le to play is set by calling Mix_LoadMUS(filename), and the lename is appended as the last argument on the commandline. This allows you to reuse the music command to play multiple les. The command will be sent signals SIGTERM to halt, SIGSTOP to pause, and SIGCONT to resume. The command program should react correctly to those signals for it to function properly with SDL Mixer. Mix_VolumeMusic has no eect when using an external music player, and Mix_GetError will have an error code set. You should set the music volume in the music players command if the music player supports that. Looping music works, by calling the command again when the previous music player process has ended. Playing music through a command uses a forked process to execute the music command. To use the internal music players set the command to NULL. NOTE: External music is not mixed by SDL mixer, so no post-processing hooks will be for music. NOTE: Playing music through an external command may not work if the sound driver does not support multiple openings of the audio device, since SDL Mixer already has the audio device open for playing samples through channels. NOTE: Commands are not totally portable, so be careful. Returns: 0 on success, or -1 on any errors, such as running out of memory.
// use mpg123 to play music Mix_Music *music=NULL; if(Mix_SetMusicCMD("mpg123 -q")==-1) { perror("Mix_SetMusicCMD"); } else { // play some mp3 file music=Mix_LoadMUS("music.mp3"); if(music) { Mix_PlayMusic(music,1); } }
See Also: Section 4.5.3 [Mix PlayMusic], page 53, Section 4.5.7 [Mix VolumeMusic], page 57
Chapter 4: Functions
63
See Also: Section 4.5.14 [Mix FadeOutMusic], page 64, Section 4.5.15 [Mix HookMusicFinished], page 65
Chapter 4: Functions
64
Gradually fade out the music over ms milliseconds starting from now. The music will be halted after the fade out is completed. Only when music is playing and not fading already are set to fade out, including paused channels. Any callback set by Mix_HookMusicFinished will be called when the music nishes fading out. Returns: 1 on success, 0 on failure.
// fade out music to finish 3 seconds from now while(!Mix_FadeOutMusic(3000) && Mix_PlayingMusic()) { // wait for any fades to complete SDL_Delay(100); }
See Also: Section 4.5.13 [Mix HaltMusic], page 63, Section 4.5.19 [Mix FadingMusic], page 69, Section 4.5.17 [Mix PlayingMusic], page 67, Section 4.5.15 [Mix HookMusicFinished], page 65
Chapter 4: Functions
65
// make a music finished function void musicFinished() { printf("Music stopped.\n"); } ... // use musicFinished for when music stops Mix_HookMusicFinished(musicFinished);
See Also: Section 4.5.13 [Mix HaltMusic], page 63, Section 4.5.14 [Mix FadeOutMusic], page 64
Chapter 4: Functions
66
Tells you the le format encoding of the music. This may be handy when used with Mix_ SetMusicPosition, and other music functions that vary based on the type of music being played. If you want to know the type of music currently being played, pass in NULL to music. Returns: The type of music or if music is NULL then the currently playing music type, otherwise MUS NONE if no music is playing. // print the type of music currently playing switch(Mix_GetMusicType(NULL)) { case MUS_NONE: MUS_CMD: printf("Command based music is playing.\n"); break; MUS_WAV: printf("WAVE/RIFF music is playing.\n"); break; MUS_MOD: printf("MOD music is playing.\n"); break; MUS_MID: printf("MIDI music is playing.\n"); break; MUS_OGG: printf("OGG music is playing.\n"); break; MUS_MP3: printf("MP3 music is playing.\n"); break; default: printf("Unknown music is playing.\n"); break; }
See Also: Section 5.3 [Mix MusicType], page 83, Section 4.6.7 [Mix SetPosition], page 78
Chapter 4: Functions
67
See Also: Section 4.5.18 [Mix PausedMusic], page 68, Section 4.5.19 [Mix FadingMusic], page 69, Section 4.5.3 [Mix PlayMusic], page 53
Chapter 4: Functions
68
See Also: Section 4.5.17 [Mix PlayingMusic], page 67, Section 4.5.8 [Mix PauseMusic], page 58, Section 4.5.9 [Mix ResumeMusic], page 59
Chapter 4: Functions
69
// check the music fade status switch(Mix_FadingMusic()) { case MIX_NO_FADING: printf("Not fading music.\n"); break; case MIX_FADING_OUT: printf("Fading out music.\n"); break; case MIX_FADING_IN: printf("Fading in music.\n"); break; }
See Also: Section 5.4 [Mix Fading], page 84, Section 4.5.18 [Mix PausedMusic], page 68, Section 4.5.17 [Mix PlayingMusic], page 67, Section 4.5.5 [Mix FadeInMusicPos], page 55, Section 4.5.14 [Mix FadeOutMusic], page 64
Chapter 4: Functions
70
Chapter 4: Functions
71
4.6 Eects
These functions are for special eects processing. Not all eects are all that special. All eects are post processing routines that are either built-in to SDL mixer or created by you. Eects can be applied to individual channels, or to the nal mixed stream which contains all the channels including music. The built-in processors: Mix_SetPanning, Mix_SetPosition, Mix_SetDistance, and Mix_SetReverseStereo, all look for an environment variable, MIX EFFECTSMAXSPEED to be dened. If the environment variable is dened these processors may use more memory or reduce the quality of the eects, all for better speed.
Chapter 4: Functions
72
arg
Hook a processor function f into a channel for post processing eects. You may just be reading the data and displaying it, or you may be altering the stream to add an echo. Most processors also have state data that they allocate as they are in use, this would be stored in the arg pointer data space. When a processor is nished being used, any function passed into d will be called, which is when your processor should clean up the data in the arg data space. The eects are put into a linked list, and always appended to the end, meaning they always work on previously registered eects output. Eects may be added multiple times in a row. Eects are cumulative this way. Returns: Zero on errors, such as a nonexisting channel.
// make a passthru processor function that does nothing... void noEffect(int chan, void *stream, int len, void *udata) { // you could work with stream here... } ... // register noEffect as a postmix processor if(!Mix_RegisterEffect(MIX_CHANNEL_POST, noEffect, NULL, NULL)) { printf("Mix_RegisterEffect: %s\n", Mix_GetError()); }
See Also: Section 4.6.2 [Mix UnregisterEect], page 73, Section 4.6.3 [Mix UnregisterAllEects], page 74
Chapter 4: Functions
73
Remove the oldest (rst found) registered eect function f from the eect list for channel. This only removes the rst found occurance of that function, so it may need to be called multiple times if you added the same function multiple times, just stop removing when Mix_UnregisterEffect returns an error, to remove all occurances of f from a channel. If the channel is active the registered eect will have its Mix_EffectDone_t function called, if it was specied in Mix_RegisterEffect. Returns: Zero on errors, such as invalid channel, or eect function not registered on channel.
// unregister the noEffect from the postmix effects // this removes all occurances of noEffect registered to the postmix while(Mix_UnregisterEffect(MIX_CHANNEL_POST, noEffect)); // you may print Mix_GetError() if you want to check it. // it should say "No such effect registered" after this loop.
See Also: Section 4.6.3 [Mix UnregisterAllEects], page 74, Section 4.6.1 [Mix RegisterEect], page 72
Chapter 4: Functions
74
This removes all eects registered to channel. If the channel is active all the registered eects will have their Mix_EffectDone_t functions called, if they were specied in Mix_ RegisterEffect. Returns: Zero on errors, such as channel not existing.
See Also: Section 4.6.2 [Mix UnregisterEect], page 73, Section 4.6.1 [Mix RegisterEect], page 72
Chapter 4: Functions
75
Hook a processor function mix func to the postmix stream for post processing eects. You may just be reading the data and displaying it, or you may be altering the stream to add an echo. Most processors also have state data that they allocate as they are in use, this would be stored in the arg pointer data space. This processor is never really nished, until the audio device is closed, or you pass NULL as the mix func. There can only be one postmix function used at a time through this method. Use Mix_RegisterEffect(MIX_CHANNEL_POST, mix_func, NULL, arg) to use multiple postmix processors. This postmix processor is run AFTER all the registered postmixers set up by Mix_RegisterEffect.
// make a passthru processor function that does nothing... void noEffect(void *udata, Uint8 *stream, int len) { // you could work with stream here... } ... // register noEffect as a postmix processor Mix_SetPostMix(noEffect, NULL);
Chapter 4: Functions
76
This eect will only work on stereo audio. Meaning you called Mix_OpenAudio with 2 channels (MIX DEFAULT CHANNELS). The easiest way to do true panning is to call Mix_SetPanning(channel, left, 254 - left); so that the total volume is correct, if you consider the maximum volume to be 127 per channel for center, or 254 max for left, this works, but about halves the eective volume. This Function registers the eect for you, so dont try to Mix_RegisterEffect it yourself. NOTE: Setting both left and right to 255 will unregister the eect from channel. You cannot unregister it any other way, unless you use Mix_UnregisterAllEffects on the channel. NOTE: Using this function on a mono audio device will not register the eect, nor will it return an error status. Returns: Zero on errors, such as bad channel, or if Mix_RegisterEffect failed.
// pan channel 1 halfway to the left if(!Mix_SetPanning(1, 255, 127)) { printf("Mix_SetPanning: %s\n", Mix_GetError()); // no panning, is it ok? }
See Also: Section 4.6.7 [Mix SetPosition], page 78, Section 4.6.3 [Mix UnregisterAllEects], page 74
Chapter 4: Functions
77
This eect simulates a simple attenuation of volume due to distance. The volume never quite reaches silence, even at max distance. NOTE: Using a distance of 0 will cause the eect to unregister itself from channel. You cannot unregister it any other way, unless you use Mix_UnregisterAllEffects on the channel. Returns: Zero on errors, such as an invalid channel, or if Mix_RegisterEffect failed.
// distance channel 1 to be farthest away if(!Mix_SetDistance(1, 255)) { printf("Mix_SetDistance: %s\n", Mix_GetError()); // no distance, is it ok? }
See Also: Section 4.6.7 [Mix SetPosition], page 78, Section 4.6.3 [Mix UnregisterAllEects], page 74
Chapter 4: Functions
78
distance
This eect emulates a simple 3D audio eect. Its not all that realistic, but it can help improve some level of realism. By giving it the angle and distance from the cameras point of view, the eect pans and attenuates volumes. If you are looking for better positional audio, using OpenAL is suggested. NOTE: Using angle and distance of 0, will cause the eect to unregister itself from channel. You cannot unregister it any other way, unless you use Mix_UnregisterAllEffects on the channel. Returns: Zero on errors, such as an invalid channel, or if Mix_RegisterEffect failed.
// set channel 2 to be behind and right, and 100 units away if(!Mix_SetPosition(2, 135, 100)) { printf("Mix_SetPosition: %s\n", Mix_GetError()); // no position effect, is it ok? }
See Also: Section 4.6.5 [Mix SetPanning], page 76, Section 4.6.6 [Mix SetDistance], page 77, Section 4.6.3 [Mix UnregisterAllEects], page 74
Chapter 4: Functions
79
Simple reverse stereo, swaps left and right channel sound. NOTE: Using a ip of 0, will cause the eect to unregister itself from channel. You cannot unregister it any other way, unless you use Mix_UnregisterAllEffects on the channel. Returns: Zero on errors, such as an invalid channel, or if Mix_RegisterEffect failed. // set the total mixer output to be reverse stereo if(!Mix_SetReverseStereo(MIX_CHANNEL_POST, 1)) { printf("Mix_SetReverseStereo: %s\n", Mix_GetError()); // no reverse stereo, is it ok? }
Chapter 5: Types
80
5 Types
These types are dened and used by the SDL mixer API.
Chapter 5: Types
81
allocated
a boolean indicating whether to free abuf when the chunk is freed. 0 if the memory was not allocated and thus not owned by this chunk. 1 if the memory was allocated and is thus owned by this chunk. Pointer to the sample data, which is in the output format and sample rate. Length of abuf in bytes. 0 = silent, 128 = max volume. This takes eect when mixing.
The internal format for an audio chunk. This stores the sample data, the length in bytes of that data, and the volume to use when mixing the sample. See Also: Section 4.2.5 [Mix VolumeChunk], page 21, Section 4.3.16 [Mix GetChunk], page 39, Section 4.2.1 [Mix LoadWAV], page 17, Section 4.2.2 [Mix LoadWAV RW], page 18, Section 4.2.6 [Mix FreeChunk], page 22, Section 5.2 [Mix Music], page 82
Chapter 5: Types
82
This is an opaque data type used for Music data. This should always be used as a pointer. Who knows why it isnt a pointer in this typedef... See Also: Section 4.5.1 [Mix LoadMUS], page 51, Section 4.5.2 [Mix FreeMusic], page 52, Section 5.1 [Mix Chunk], page 81
Chapter 5: Types
83
typedef enum { MUS_NONE, MUS_CMD, MUS_WAV, MUS_MOD, MUS_MID, MUS_OGG, MUS_MP3 } Mix_MusicType;
Return values from Mix_GetMusicType are of these enumerated values. If no music is playing then MUS NONE is returned. If music is playing via an external command then MUS CMD is returned. Otherwise they are self explanatory. See Also: Section 4.5.16 [Mix GetMusicType], page 66
Chapter 5: Types
84
Return values from Mix_FadingMusic and Mix_FadingChannel are of these enumerated values. If no fading is taking place on the queried channel or music, then MIX NO FADING is returned. Otherwise they are self explanatory. See Also: Section 4.3.15 [Mix FadingChannel], page 38, Section 4.5.19 [Mix FadingMusic], page 69
Chapter 5: Types
85
typedef void (*Mix_EffectFunc_t)(int chan, void *stream, int len, void *udata ); The channel number that this eect is eecting now. MIX CHANNEL POST is passed in for post processing eects over the nal mix. The buer containing the current sample to process. The length of stream in bytes. User data pointer that was passed in to Mix_RegisterEffect when registering this eect processor function.
chan
This is the prototype for eect processing functions. These functions are used to apply eects processing on a sample chunk. As a channel plays a sample, the registered eect functions are called. Each eect would then read and perhaps alter the len bytes of stream. It may also be advantageous to keep the eect state in the udata, with would be setup when registering the eect function on a channel. See Also: Section 4.6.1 [Mix RegisterEect], page 72 Section 4.6.2 [Mix UnregisterEect], page 73
Chapter 5: Types
86
typedef void (*Mix_EffectDone_t)(int chan, void *udata ); The channel number that this eect is eecting now. MIX CHANNEL POST is passed in for post processing eects over the nal mix. User data pointer that was passed in to Mix_RegisterEffect when registering this eect processor function.
chan
udata
This is the prototype for eect processing functions. This is called when a channel has nished playing, or halted, or is deallocated. This is also called when a processor is unregistered while processing is active. At that time the eects processing function may want to reset some internal variables or free some memory. It should free memory at least, because the processor could be freed after this call. See Also: Section 4.6.1 [Mix RegisterEect], page 72 Section 4.6.2 [Mix UnregisterEect], page 73
Chapter 6: Denes
87
6 Denes
MIX MAJOR VERSION 1 SDL mixer library major number at compilation time MIX MINOR VERSION 2 SDL mixer library minor number at compilation time MIX PATCHLEVEL 4 SDL mixer library patch level at compilation time MIX CHANNELS 8 The default mixer has this many simultaneous mixing channels after the rst call to Mix_OpenAudio. MIX DEFAULT FREQUENCY 22050 Good default sample rate in Hz (samples per second) for PC sound cards. MIX DEFAULT FORMAT AUDIO_S16SYS The suggested default is signed 16bit samples in host byte order. MIX DEFAULT CHANNELS 2 Stereo sound is a good default. MIX MAX VOLUME 128 Maximum value for any volume setting. This is currently the same as SDL MIX MAXVOLUME. MIX CHANNEL POST -2 This is the channel number used for post processing eects. MIX EFFECTSMAXSPEED "MIX_EFFECTSMAXSPEED" A convience denition for the string name of the environment variable to dene when you desire the internal eects to sacrice quality and/or RAM for speed. The environment variable must be set (else nonexisting) before Mix_OpenAudio is called for the setting to take eect.
Chapter 7: Glossary
88
7 Glossary
Byte Order Also known as Big-Endian. Which means the most signicant byte comes rst in storage. Sparc and Motorola 68k based chips are MSB ordered. (SDL denes this as SDL BYTEORDER==SDL BIG ENDIAN) Little-Endian(LSB) is stored in the opposite order, with the least signicant byte rst in memory. Intel and AMD are two LSB machines. (SDL denes this as SDL BYTEORDER==SDL LIL ENDIAN)
Index
89
Index
(Index is nonexistent)