annotate mixer/tutorial.txt @ 562:7e08477b0fc1

MP3 decoder upgrade work. Ripped out SMPEG and mpglib support, replaced it with "mpg123.c" and libmpg123. libmpg123 is a much better version of mpglib, so it should solve all the problems about MP3's not seeking, or most modern MP3's not playing at all, etc. Since you no longer have to make a tradeoff with SMPEG for features, and SMPEG is basically rotting, I removed it from the project. There is still work to be done with libmpg123...there are MMX, 3DNow, SSE, Altivec, etc decoders which we don't have enabled at the moment, and the build system could use some work to make this compile more cleanly, etc. Still: huge win.
author Ryan C. Gordon <icculus@icculus.org>
date Fri, 30 Jan 2009 02:44:47 -0500
parents 3a3807dcf57f
children
rev   line source
478
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
1
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
2 SDL_sound version 2.0: Your Mixer, And Welcome To It.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
3
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
4
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
5 SDL_sound v2's major addition is a software mixer. There are some other new
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
6 features, but this is the Big New Thing.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
7
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
8
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
9 Some notable features of this mixer:
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
10 - No clamping at mix time. Most SDL-based mixing is done via SDL_MixAudio(),
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
11 which mixes two samples together, clamping to 16-bits, and then mixes the
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
12 next sample into this already-clamped buffer. This can lead to audio
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
13 distortion. SDL_sound mixes all samples into a 32-bit floating point buffer
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
14 before passing it to the audio device, which means no unnecessary clamping.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
15 It also means it can be more optimized for MacOS X's CoreAudio and other
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
16 next-gen audio subsystems, which require you to feed it float32 data.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
17
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
18 - Optimized mixing: MMX, SSE, 3DNow!, and Altivec are used internally where
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
19 appropriate. (er...they WILL be, at least!)
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
20
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
21 - Multiple "music" files. SDL_mixer is notorious for making a distinction
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
22 between "sound" and "music" files (that is, things that can be trivially
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
23 decoded to a waveform without bloating the memory footprint vs. things that
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
24 can't), and only allows mixing of one music file at a time. SDL_sound
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
25 doesn't bother with this distinction, which means you are free to mix any
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
26 combination of audio formats at the same time.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
27
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
28 - No "channels". If you want to mix 1,000 audio files and have the hardware
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
29 to cover it, you can. You don't have to manage playback channels. There
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
30 isn't a seperate "music" channel, since "music" isn't treated differently
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
31 from any other audio.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
32
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
33 - Lots of formats. SDL_sound already decodes a huge number of audio formats.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
34 As the mixer is layered on top of this, all of the format support comes
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
35 for free.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
36
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
37 - Can handle non-power-of-two resampling. If your samples are at 8000Hz
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
38 and the audio hardware is at 11000Hz, this doesn't cause output problems.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
39
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
40 - Control over buffering and mixing. SDL_sound already lets you control how
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
41 much audio is prebuffered and predecoded; this carries over to the mixer,
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
42 so you can customize how your resources are being used on the fly.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
43
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
44 - Flexible enough for those that need to micromanage mixing, but dirt simple
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
45 to for those that just want to make some noise.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
46
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
47 - It can be compiled out if you just want the 1.0 API for decoding formats.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
48 (initializing the mixer subsystem in this case will fail, but for binary
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
49 compatibility, the entry points will still exist).
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
50
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
51 A brief tutorial follows.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
52
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
53
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
54 Example #1: Play a sound and get the heck out of there.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
55
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
56 #include "SDL_sound.h"
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
57
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
58 int main(int argc, char **argv)
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
59 {
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
60 Sound_MixInit(NULL); // start the mixer; don't care what format.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
61 Sound_Sample *hello = Sound_NewSampleFromFile("hello.wav", NULL, 10240);
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
62 Sound_MixPlay(hello);
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
63 while (Sound_MixPlaying(hello))
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
64 SDL_Delay(100); // wait around; mixing is in a seperate thread!
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
65 Sound_FreeSample(hello);
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
66 Sound_MixDeinit();
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
67 return(0);
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
68 }
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
69
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
70 Every tutorial needs a "Hello World" example.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
71 That will play hello.wav, wait for it to finish, and terminate the program.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
72 But that's not really mixing! To qualify, you'd need to play two sounds at
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
73 once. So let's do that:
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
74
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
75
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
76 Example #2: Mixing two sounds.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
77
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
78 #include "SDL_sound.h"
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
79
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
80 int main(int argc, char **argv)
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
81 {
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
82 Sound_MixInit(NULL); // start the mixer; don't care what format.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
83 Sound_Sample *hello = Sound_NewSampleFromFile("hello.wav", NULL, 10240);
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
84 Sound_Sample *music = Sound_NewSampleFromFile("icculus.ogg", NULL, 10240);
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
85 Sound_MixPlay(music);
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
86 while (Sound_MixPlaying(music))
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
87 {
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
88 if (!Sound_MixPlaying(hello))
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
89 {
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
90 Sound_Rewind(hello);
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
91 Sound_MixPlay(hello);
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
92 }
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
93 SDL_Delay(100); // wait around.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
94 }
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
95 Sound_FreeSample(music);
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
96 Sound_FreeSample(hello); // will stop if it happens to still be playing.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
97 Sound_MixDeinit();
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
98 return(0);
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
99 }
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
100
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
101 Same deal, but we play some music ("Icculus in San Jose" from the talented
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
102 Emmett Plant, in this case). We also load our "hello" sound from the previous
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
103 example. While the music is playing, we check if "hello" is playing, and if
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
104 not, we set it up to play again. Note that the two sounds are playing at the
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
105 same time, mixed together. Cool, huh?
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
106
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
107 You might notice that we called Sound_Rewind() on the hello sample. This isn't
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
108 part of the mixer itself, and is a function from SDL_sound v1, before there
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
109 was a mixer at all. This illustrates that you can use the usual SDL_sound
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
110 methods to manipulate a sample in the mixer, including seeking and predecoding.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
111 These are safe operations even while the sample is playing.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
112
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
113 That's about all you need to know to effectively use the mixer. Everything
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
114 after that is extra credit.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
115
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
116
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
117 Extra credit #1: Mixer Attributes.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
118
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
119 An API's got to know its limitations. SDL_sound isn't meant to be a robust 3D
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
120 spatialization library. For that, one should look to the excellent OpenAL API
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
121 at http://www.openal.org/. Still, for many reasons, OpenAL might not be a good
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
122 fit: it doesn't support many audio formats (and all formats except uncompressed
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
123 integer PCM are optional extensions to the API), it is less likely to
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
124 support your platform and audio output target than SDL, and it is more
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
125 complicated to feed it streamed audio. While not as robust as AL's feature
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
126 set, SDL_sound v2 provides a handful of useful attributes you can set on a
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
127 sample to alter its playback.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
128
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
129
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
130 Basic Attribute #1: Looping.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
131
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
132 Checking a sample's playing state in a loop just so you know when to restart
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
133 it has two problems: first, it's a pain in the butt, and second, there may
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
134 be a gap in the audio between when the sound starts and when you're able to
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
135 restart it. To remedy this, SDL_sound lets you flag a sample as "looping" so
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
136 you don't have to micromanage it. It will continue to rewind and play until
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
137 you explicitly stop it. Let's take our last example and do this right:
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
138
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
139
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
140 Example #3: Mixing two sounds with better looping.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
141
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
142 #include "SDL_sound.h"
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
143
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
144 int main(int argc, char **argv)
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
145 {
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
146 Sound_MixInit(NULL); // start the mixer; don't care what format.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
147 Sound_Sample *hello = Sound_NewSampleFromFile("hello.wav", NULL, 10240);
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
148 Sound_Sample *music = Sound_NewSampleFromFile("icculus.ogg", NULL, 10240);
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
149 Sound_SetAttribute(hello, SOUND_ATTR_LOOPING, 1); // turn on looping.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
150 Sound_MixPlay(music);
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
151 Sound_MixPlay(hello);
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
152 while (Sound_MixPlaying(music))
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
153 SDL_Delay(100); // wait around.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
154 Sound_FreeSample(music);
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
155 Sound_FreeSample(hello); // will stop now.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
156 Sound_MixDeinit();
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
157 return(0);
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
158 }
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
159
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
160 ...it's that easy.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
161
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
162
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
163 Basic attribute #2: Fire and forget
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
164
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
165 You'll notice in previous examples that we are taking the pains to explicitly
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
166 free the resources associated with a sample via the Sound_FreeSample() call.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
167 In a small program like this, it's easy to be tidy and sweep up after one
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
168 or two hardcoded sounds, but when you are managing a lot of different sounds,
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
169 or a lot of copies of the same sound, this can become tedious. Case in point:
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
170 laser beams.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
171
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
172 Let's say you've got a space fighter game, with a bunch of ships flying
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
173 around and shooting at each other. Every time they fire a laser, do you really
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
174 want to take the effort to decide when it is done and clean it up? You want
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
175 to, quite literally in this case, "fire and forget" the sound...that is, you
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
176 want the mixer to playback the audio and then clean it up without further
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
177 action or intervention from you.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
178
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
179 So let's take our previous example and adjust it to clean up after us.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
180
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
181
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
182 Example #4: Fire and forget playback.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
183
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
184 #include "SDL_sound.h"
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
185
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
186 int main(int argc, char **argv)
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
187 {
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
188 Sound_MixInit(NULL); // start the mixer; don't care what format.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
189 Sound_Sample *hello = Sound_NewSampleFromFile("hello.wav", NULL, 10240);
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
190 Sound_Sample *music = Sound_NewSampleFromFile("icculus.ogg", NULL, 10240);
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
191 Sound_SetAttribute(hello, SOUND_ATTR_FIREANDFORGET, 1);
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
192 Sound_SetAttribute(music, SOUND_ATTR_FIREANDFORGET, 1);
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
193 Sound_MixPlay(music); // play once, then call Sound_FreeSample() for you.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
194 Sound_MixPlay(hello); // play once, then call Sound_FreeSample() for you.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
195 while (Sound_MixPlayingCount() > 0)
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
196 SDL_Delay(100); // wait around.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
197
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
198 // Don't need Sound_FreeSample() here anymore!
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
199
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
200 Sound_MixDeinit();
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
201 return(0);
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
202 }
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
203
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
204 So everything was deallocated automatically, and your mother didn't even have
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
205 to come along and tell you to clean up this pig sty! She is very proud of you
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
206 right now, I assure you.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
207
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
208 You'll note that we call Sound_MixPlayingCount() to see if the music finished.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
209 You have to do this because the "music" sample is invalid once it gets pushed
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
210 through Sound_FreeSample(), which will happen as soon as the mixer is done
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
211 with it. To avoid touching deallocated memory, we just ask the mixer if
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
212 anything is still playing.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
213
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
214 Also, common sense dictates that looping sounds never get to the "forget"
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
215 part of "fire and forget", since they don't stop playing. You can either
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
216 manually halt them or turn off the looping, though, and then they'll clean
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
217 themselves up.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
218
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
219
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
220 Basic attribute #3: Per-channel Gain.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
221
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
222 If you can tweak the volume of the left or right channel on a sample, you can
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
223 accomplish (or at least fake) a surprising number of simple sound effects.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
224 Therefore the mixer allows you to do just this, and then builds a few features
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
225 on top of this magic.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
226
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
227 This is accomplished by tweaking the "gain" of a given channel. "Gain" is just
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
228 a fancy way of saying "volume". You specify it as a floating point number,
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
229 usually in the range of 0.0f to 2.0f. If you set the gain to 0.0f, it results
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
230 in silence, and 1.0f results in no change at all. 0.5f halves the volume and
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
231 2.0f doubles it. As you might have guessed, the sample gets multiplied by
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
232 this value.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
233
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
234 SDL_sound's mixer lets you tweak each channel in a sample individually. Right
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
235 now we're limited to mono (one channel) and stereo (two channel) sounds, but
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
236 this will probably be enhanced at some point. It's worth noting that this
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
237 refers not to the sample itself but to the speakers where they play. This
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
238 means you can set the left and right channels of a sample, even though the
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
239 sample itself only has one. Since a 2-speaker setup will promote a mono sound
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
240 to stereo (same waveform is fed to each speaker), you can tweak it to play at
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
241 different volumes in the left and right.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
242
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
243
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
244 So to rehash our tired hello world example again...
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
245
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
246 Example #5: Per-channel gain.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
247
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
248 #include "SDL_sound.h"
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
249
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
250 int main(int argc, char **argv)
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
251 {
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
252 Sound_MixInit(NULL); // start the mixer; don't care what format.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
253 Sound_Sample *hello = Sound_NewSampleFromFile("hello.wav", NULL, 10240);
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
254
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
255 // Every channel's gain defaults to 1.0f, or no adjustment.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
256
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
257 Sound_SetAttribute(hello, SOUND_ATTRGAIN0, 0.0f); // left chan==silence.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
258 Sound_MixPlay(hello); // plays just right channel.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
259 while (Sound_MixPlaying(hello))
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
260 SDL_Delay(100); // wait around.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
261
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
262 Sound_SetAttribute(hello, SOUND_ATTRGAIN0, 1.0f); // left chan==normal
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
263 Sound_SetAttribute(hello, SOUND_ATTRGAIN1, 0.0f); // right chan==silence
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
264 Sound_MixPlay(hello); // plays just left channel.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
265 while (Sound_MixPlaying(hello))
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
266 SDL_Delay(100); // wait around.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
267
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
268 Sound_FreeSample(hello);
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
269 Sound_MixDeinit();
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
270 return(0);
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
271 }
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
272
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
273
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
274 This played the hello sound twice, once in each speaker. Simple.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
275
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
276 Well, almost simple. If you only have mono output (one speaker), then this
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
277 will play silence the first time (channel 0 set to silence), then the sound
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
278 at normal volume the second time (channel 0, the only speaker, set to normal).
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
279 In a 1-speaker setup, screwing with the second channel is ignored.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
280
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
281 If this is going to be a pain for you to track yourself, you can use
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
282 Sound_MixInit() to set up a stereo environment and let it dither everything
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
283 down to one speaker behind the scenes if need be. Generally, this isn't a
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
284 huge concern, though.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
285
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
286
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
287 Extra Credit #2: Fading
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
288
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
289 Sometimes you want to fade out (or fade in) a sound over time...this is
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
290 handy when ending a game level. It's a nicer effect to silence everything
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
291 over some small amount of time than to abruptly kill all the noise. This is
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
292 more pleasant for the end-user.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
293
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
294 You could accomplish this by tweaking each channel of all your samples' gain
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
295 over time, but this is another one of those things that are annoying to
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
296 micromanage. The mixer has to constantly pay attention to these samples anyhow,
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
297 why should you do it, too?
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
298
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
299 SDL_sound gives you a means to instruct the mixer to take care of this.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
300
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
301
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
302 Example #6: Fading a sound.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
303
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
304 #include "SDL_sound.h"
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
305
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
306 int main(int argc, char **argv)
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
307 {
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
308 Sound_MixInit(NULL); // start the mixer; don't care what format.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
309 Sound_Sample *music = Sound_NewSampleFromFile("icculus.ogg", NULL, 10240);
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
310 Sound_MixPlay(music); // Start music playing.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
311 Sound_SetAttribute(music, SOUND_ATTR_FADEOUT, 10000);
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
312 SDL_Delay(10000);
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
313 Sound_SetAttribute(music, SOUND_ATTR_FADEIN, 10000);
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
314 SDL_Delay(10000);
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
315 Sound_FreeSample(music);
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
316 Sound_MixDeinit();
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
317 return(0);
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
318 }
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
319
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
320
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
321 So this starts our favorite song playing, and tells it to fade to silence
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
322 smoothly over 10000 milliseconds (that is, 10 seconds). Since we know how
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
323 long we want this to take, we lazily call SDL_Delay() to wait that long; the
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
324 mixer works in another thread, so we have the luxury of doing nothing here.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
325 Then we fade it back in over another 10 seconds before exiting.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
326
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
327 It's worth noting a few things here:
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
328 First, the FADEOUT attribute uses the same mechanism as SetGain() under the
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
329 hood when mixing, but the two attributes exist seperately: if you double the
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
330 gain (2.0f), the sound will drop in volume twice as much each time the fading
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
331 updates, but it's still going to go from twice-as-loud to silence in the
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
332 same amount of time (10000 milliseconds in this case).
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
333
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
334 When a sample is totally silent, either because it faded out or you set its
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
335 gain to 0.0f, it is still playing! If you were to turn the volume back up
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
336 30 seconds after the fade completes, you'd hear the sound as it would be at
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
337 that 30 second moment as if you hadn't silenced it at all. This has a few
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
338 important ramifications:
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
339 1) It's still taking CPU time. Maybe not as much, since we can choose not
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
340 to mix when the gain is 0.0f, but in order to keep the sound "playing"
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
341 we might need to decode more of it, which means CPU time and memory
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
342 usage and such. Best to halt a silent sound if you aren't going to need
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
343 it.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
344 2) Sound_MixPlayingCount() might be > 0 even though you don't hear noise.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
345 3) A sound might not be where you left it. Keep better track of your things!
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
346
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
347 You might also notice that we called Sound_FreeSample() on a playing sample.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
348 This is legal. If a sample is playing when you free it, the mixer knows to
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
349 halt it first.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
350
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
351
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
352 Extra Credit #3: Halting
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
353
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
354 SDL_sound's mixer is a little different than most, in that there aren't
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
355 seperate playing states. "Halting" a mixing sample means you took it out of
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
356 the mixing list. "Playing" it means you put it back in, and it picks up the
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
357 mixing with the sample as it found it.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
358
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
359 If you want something anologous to that "stop" button in WinAmp, you would
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
360 halt the sample and then call Sound_Rewind() on it. Next time you start it
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
361 playing, it'll be playing from the start of the sample. If you didn't call
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
362 Sound_Rewind() first, it'll be playing from where you halted it. That's more
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
363 like clicking WinAmp's "pause" button.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
364
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
365 However, there are times when you want everything to stop at once. Just
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
366 looping over every sample and halting them isn't any good, since some might
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
367 play just a tiny bit longer...it's a lovely bug called a "race condition".
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
368
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
369 And, as I'm sure you've heard me say before, why do a lot of work to manage
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
370 stuff that the mixer has to manage itself anyhow? You should learn to
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
371 delegate more, you control freak.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
372
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
373
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
374 Example #7: Halting.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
375
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
376 #include "SDL_sound.h"
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
377
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
378 int main(int argc, char **argv)
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
379 {
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
380 Sound_MixInit(NULL); // start the mixer; don't care what format.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
381 Sound_Sample *hello = Sound_NewSampleFromFile("hello.wav", NULL, 10240);
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
382 Sound_Sample *chatter = Sound_NewSampleFromFile("chatter.wav", NULL, 10240);
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
383 Sound_Sample *music = Sound_NewSampleFromFile("icculus.ogg", NULL, 10240);
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
384 Sound_MixPlay(music);
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
385
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
386 Sound_MixPlay(hello);
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
387 while (Sound_MixPlaying(hello)) SDL_Delay(100); // wait around.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
388 Sound_MixPlay(hello);
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
389 while (Sound_MixPlaying(hello)) SDL_Delay(100); // wait around.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
390 Sound_MixPlay(hello);
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
391 while (Sound_MixPlaying(hello)) SDL_Delay(100); // wait around.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
392
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
393 Sound_MixHalt(music); // halt the music.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
394
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
395 Sound_MixPlay(hello);
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
396 while (Sound_MixPlaying(hello)) SDL_Delay(100); // wait around.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
397 Sound_MixPlay(hello);
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
398 while (Sound_MixPlaying(hello)) SDL_Delay(100); // wait around.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
399 Sound_MixPlay(hello);
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
400 while (Sound_MixPlaying(hello)) SDL_Delay(100); // wait around.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
401
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
402 Sound_MixPlay(music); // start the music where it left off.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
403 Sound_MixPlay(chatter); // start the chatter.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
404
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
405 SDL_Delay(3000); // let them play.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
406 Sound_MixHalt(NULL); // halt _everything_ that's playing.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
407 SDL_Delay(3000); // waste some time.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
408 Sound_MixPlay(music); // start the music where it left off.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
409 Sound_MixPlay(chatter); // start the chatter where it left off.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
410 SDL_Delay(3000); // waste some more time.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
411
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
412 Sound_FreeSample(music); // clean up and quit.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
413 Sound_FreeSample(chatter);
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
414 Sound_FreeSample(hello);
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
415 Sound_MixDeinit();
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
416 return(0);
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
417 }
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
418
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
419
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
420 Ok, you following? That plays the music, plays "hello" three times while the
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
421 music is playing, halts the music and plays hello three times without anything
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
422 else, restarts the music where it left off mixed with "chatter" for three
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
423 seconds, stops everything (music and chatter in this case), waits three more
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
424 seconds of silence, restarts the music and chatter where it left off and
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
425 lets them play for three more seconds. Then it shuts it all down and goes
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
426 home.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
427
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
428 Fun, huh?
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
429
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
430 There are some notable exceptions to this rule. When a sound gets to the end
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
431 of its mixing, it either halts or (if set looping) rewinds and starts playing
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
432 again without missing a beat. For these, you don't have to manually halt
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
433 (or manually restart, as it were).
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
434
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
435
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
436 You now have everything you need to make a game with robust audio. But for
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
437 some of you, that's not enough. You're never satisfied. You need the section
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
438 of this tutorial written for...
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
439
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
440
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
441 THE HARDCORE.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
442
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
443 (These sections are brief and lack full examples. If you're hardcore, you
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
444 probably don't read wussy tutorials anyhow.)
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
445
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
446
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
447 Hardcore #1: low-overhead copying of a sample.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
448
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
449 Let's say you've got a sound file that represents a laser blast. Everytime a
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
450 shot is fired in your game, you don't want to have the overhead of reloading
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
451 it from disk, decoding and mixing it on the fly!
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
452
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
453 Here are some tips for your efficiency:
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
454
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
455 - Opt for an uncompressed format, such as a standard .WAV file or even
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
456 raw PCM. For small, frequently used sounds, the bigger memory footprint
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
457 is usually an acceptable tradeoff to constant redecoding. In some cases,
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
458 we've found that compressing to, say, .ogg format actually makes the
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
459 file bigger if it's a very short sound.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
460
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
461 - Put your sound into a memory block and point multiple memory RWOPS at
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
462 it: one per playing sound. There are functions in SDL_sound 2
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
463 for allocating these from a pool, which reduces allocation overhead
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
464 and memory fragmentation, and eliminates multiple trips to the disk
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
465 when you "read" the sound.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
466
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
467 - Sound_Sample structures are allocated in a pool, too, so throwaway
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
468 sounds (specifically, ones using pooled RWOPS) don't thrash system
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
469 resources. Good for those fire-and-forget effects.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
470
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
471 - It's trivial to roll a reference-counting RWOPS that lets you use the
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
472 same memory block for several playing sounds, and when the last one
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
473 closes it (all related Sound_Samples go through Sound_FreeSample()), it
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
474 deletes the original memory block. Handy if you only want to loosely
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
475 manage those buffers.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
476
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
477 - Cull samples if you're playing too many. The app can decide which sounds
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
478 are important and assign them a priority, and let only the first X
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
479 highest priority sounds actually mix.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
480
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
481 - Alternately, if you can swallow the memory: take a highly-compressed
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
482 file and put it into a Sound_Sample, call Sound_DecodeAll. Now, use
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
483 the sample's "decoded" field as raw PCM for other Sound_Samples using
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
484 above tricks. When you are done, clean up the other samples first, then
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
485 call Sound_FreeSample() on this one. This is extremely useful if you
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
486 want to reduce CPU usage for one sound that is otherwise compressed.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
487 Memory usage doesn't grow exponentially with each simulataneous mixing
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
488 of this sound, because everyone is feeding from the same memory block,
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
489 so each new sample instance adds some bytes for the structures (which
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
490 might have been allocated in the pool already anyhow).
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
491
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
492
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
493 Hardcore #2: Predecoding and buffer sizes.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
494
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
495 Take advantage of the 1.0 API for predecoding and altering the decode buffer
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
496 size. This gives you control over the memory/CPU tradeoff at mix time, as the
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
497 mixer will call Sound_Decode() when it needs more data from a playing sample.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
498 How much decoding is done at that point depends on how much buffering is
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
499 available. If you predecode the whole thing with Sound_DecodeAll(), then the
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
500 mixer can focus on mixing and not spend time decoding.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
501
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
502
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
503
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
504 Hardcore #3: Global gain, global fade.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
505
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
506 Most attributes that apply to one sample can be applied to all by passing a
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
507 NULL for the first argument to Sound_SetAttribute(). Gain and fade are
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
508 examples of this. If you want everything to fade out at once, this is the
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
509 best, race-condition free way to do it.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
510
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
511 Note that global attributes don't override (or overwrite) per-sample
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
512 attributes. If you set a sample's gain to 2.0 and the global gain to 0.5, the
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
513 sound plays at normal (1.0) gain...the sample's gain is still 2.0 when you
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
514 change the global gain thereafter.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
515
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
516
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
517 Hardcore #4: Postmix callbacks.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
518
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
519 You can register a callback function per-sample that is called when the mixer
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
520 has finished its work and is about to send the data to the audio hardware.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
521 These generally run in seperate threads on most platforms, and as such must be
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
522 protected from your main code with mutexes.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
523
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
524 These are useful if you are are writing a media player and want to show some
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
525 sort of visual feedback based on the playing audio data, or if you want to
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
526 tweak the sound with your own special effects.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
527
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
528
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
529 Hardcore #5: Sample finished callback.
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
530
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
531 You can register a callback function per-sample that is called when the mixer
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
532 has completely finished mixing a non-looping sample. This is largely a nod to
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
533 SDL_mixer, where this was the most convenient way to clean up fire-and-forget
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
534 sounds, but most people will want to let SDL_sound handle those. This has
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
535 other good uses: it lets you know when sound events are complete if you are
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
536 adding cinematics/cut-scenes to your program, or perhaps when it's safe for
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
537 characters to speak again (it's strange when one actor is speaking two
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
538 overlapping lines of dialogue, for example).
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
539
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
540
523
3a3807dcf57f Minor tutorial.txt update.
Ryan C. Gordon <icculus@icculus.org>
parents: 478
diff changeset
541 Hardcore #6: Procedural samples.
3a3807dcf57f Minor tutorial.txt update.
Ryan C. Gordon <icculus@icculus.org>
parents: 478
diff changeset
542 !!! WRITEME: Hook up a RAW Sound_Sample to a RWOPS that generates sound on
3a3807dcf57f Minor tutorial.txt update.
Ryan C. Gordon <icculus@icculus.org>
parents: 478
diff changeset
543 !!! WRITEME: read, so you can mix in a procedural sample instead of just
3a3807dcf57f Minor tutorial.txt update.
Ryan C. Gordon <icculus@icculus.org>
parents: 478
diff changeset
544 !!! WRITEME: pre/post mixing.
3a3807dcf57f Minor tutorial.txt update.
Ryan C. Gordon <icculus@icculus.org>
parents: 478
diff changeset
545
3a3807dcf57f Minor tutorial.txt update.
Ryan C. Gordon <icculus@icculus.org>
parents: 478
diff changeset
546
3a3807dcf57f Minor tutorial.txt update.
Ryan C. Gordon <icculus@icculus.org>
parents: 478
diff changeset
547
3a3807dcf57f Minor tutorial.txt update.
Ryan C. Gordon <icculus@icculus.org>
parents: 478
diff changeset
548 Hardcore #7: Your suggestion here!
478
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
549
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
550 The goal is to try and make audio work fairly painless for the game developer,
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
551 which means that if there is a good way to generalize functionality into the
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
552 mixer layer, we probably should. Comments are welcome!
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
553
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
554 It's worth noting that this tutorial covers common usage patterns and the Big
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
555 Important Things, so a lot of support API isn't covered here. For example,
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
556 important things like being able to query sample attributes weren't important
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
557 enough to mention here, but that doesn't mean you can't do it).
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
558
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
559 // end of mixer.txt ...
15a540505a02 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
560