annotate mixer/tutorial.txt @ 591:8faf61a640f0 tip

Resynced fixes for unit conversion bugs in the Ogg Tremor decoder from SoundDecoder/ALmixer. Ogg Vorbis uses seconds and we multiply by 1000 to convert to milliseconds. But Ogg Tremor already uses milliseconds but I was still multiplying by 1000.
author Eric Wing <ewing . public |-at-| gmail . com>
date Thu, 25 Oct 2012 16:34:18 -0700
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