Mercurial > SDL_sound_CoreAudio
comparison playsound/playsound.c @ 270:cf8c0bbbdc19
--volume control.
author | Ryan C. Gordon <icculus@icculus.org> |
---|---|
date | Thu, 07 Mar 2002 09:38:51 +0000 |
parents | c54eae85f5f1 |
children | 0ac181b5adc6 |
comparison
equal
deleted
inserted
replaced
269:e11b87a3ec91 | 270:cf8c0bbbdc19 |
---|---|
24 * | 24 * |
25 * This file written by Ryan C. Gordon. (icculus@clutteredmind.org) | 25 * This file written by Ryan C. Gordon. (icculus@clutteredmind.org) |
26 */ | 26 */ |
27 | 27 |
28 #include <stdio.h> | 28 #include <stdio.h> |
29 #include <stdlib.h> | |
29 #include <string.h> | 30 #include <string.h> |
30 #include <assert.h> | 31 #include <assert.h> |
31 #include <signal.h> | 32 #include <signal.h> |
32 #include "SDL.h" | 33 #include "SDL.h" |
33 #include "SDL_sound.h" | 34 #include "SDL_sound.h" |
104 " --rate n Playback at sample rate of n HZ.\n" | 105 " --rate n Playback at sample rate of n HZ.\n" |
105 " --format fmt Playback in fmt format (see below).\n" | 106 " --format fmt Playback in fmt format (see below).\n" |
106 " --channels n Playback on n channels (1 or 2).\n" | 107 " --channels n Playback on n channels (1 or 2).\n" |
107 " --decodebuf n Buffer n decoded bytes at a time (default %d).\n" | 108 " --decodebuf n Buffer n decoded bytes at a time (default %d).\n" |
108 " --audiobuf n Buffer n samples to audio device (default %d).\n" | 109 " --audiobuf n Buffer n samples to audio device (default %d).\n" |
110 " --volume n Playback volume multiplier (default 1.0).\n" | |
109 " --version Display version information and exit.\n" | 111 " --version Display version information and exit.\n" |
110 " --decoders List supported data formats and exit.\n" | 112 " --decoders List supported data formats and exit.\n" |
111 " --predecode Decode entire sample before playback.\n" | 113 " --predecode Decode entire sample before playback.\n" |
112 " --loop Loop playback until SIGINT.\n" | 114 " --loop Loop playback until SIGINT.\n" |
113 " --credits Shameless promotion.\n" | 115 " --credits Shameless promotion.\n" |
173 | 175 |
174 static Uint8 *decoded_ptr = NULL; | 176 static Uint8 *decoded_ptr = NULL; |
175 static Uint32 decoded_bytes = 0; | 177 static Uint32 decoded_bytes = 0; |
176 static int predecode = 0; | 178 static int predecode = 0; |
177 static int looping = 0; | 179 static int looping = 0; |
180 static int wants_volume_change = 0; | |
181 static float volume = 1.0; | |
178 | 182 |
179 /* | 183 /* |
180 * This updates (decoded_bytes) and (decoder_ptr) with more audio data, | 184 * This updates (decoded_bytes) and (decoder_ptr) with more audio data, |
181 * taking into account looping and/or predecoding. | 185 * taking into account looping and/or predecoding. |
182 */ | 186 */ |
217 assert(0); /* shouldn't ever hit this point. */ | 221 assert(0); /* shouldn't ever hit this point. */ |
218 return(0); | 222 return(0); |
219 } /* read_more_data */ | 223 } /* read_more_data */ |
220 | 224 |
221 | 225 |
226 static void memcpy_with_volume(Sound_Sample *sample, | |
227 Uint8 *dst, Uint8 *src, int len) | |
228 { | |
229 int i; | |
230 Uint16 *u16src = NULL; | |
231 Uint16 *u16dst = NULL; | |
232 Sint16 *s16src = NULL; | |
233 Sint16 *s16dst = NULL; | |
234 | |
235 if (!wants_volume_change) | |
236 { | |
237 memcpy(dst, src, len); | |
238 return; | |
239 } | |
240 | |
241 /* !!! FIXME: This would be more efficient with a lookup table. */ | |
242 switch (sample->desired.format) | |
243 { | |
244 case AUDIO_U8: | |
245 for (i = 0; i < len; i++, src++, dst++) | |
246 *dst = (Uint8) (((float) (*src)) * volume); | |
247 break; | |
248 | |
249 case AUDIO_S8: | |
250 for (i = 0; i < len; i++, src++, dst++) | |
251 *dst = (Sint8) (((float) (*src)) * volume); | |
252 break; | |
253 | |
254 case AUDIO_U16LSB: | |
255 u16src = (Uint16 *) src; | |
256 u16dst = (Uint16 *) dst; | |
257 for (i = 0; i < len; i += sizeof (Uint16), u16src++, u16dst++) | |
258 { | |
259 *u16dst = (Uint16) (((float) (SDL_SwapLE16(*u16src))) * volume); | |
260 *u16dst = SDL_SwapLE16(*u16dst); | |
261 } | |
262 break; | |
263 | |
264 case AUDIO_S16LSB: | |
265 s16src = (Sint16 *) src; | |
266 s16dst = (Sint16 *) dst; | |
267 for (i = 0; i < len; i += sizeof (Sint16), s16src++, s16dst++) | |
268 { | |
269 *s16dst = (Sint16) (((float) (SDL_SwapLE16(*s16src))) * volume); | |
270 *s16dst = SDL_SwapLE16(*s16dst); | |
271 } | |
272 break; | |
273 | |
274 case AUDIO_U16MSB: | |
275 u16src = (Uint16 *) src; | |
276 u16dst = (Uint16 *) dst; | |
277 for (i = 0; i < len; i += sizeof (Uint16), u16src++, u16dst++) | |
278 { | |
279 *u16dst = (Uint16) (((float) (SDL_SwapBE16(*u16src))) * volume); | |
280 *u16dst = SDL_SwapBE16(*u16dst); | |
281 } | |
282 break; | |
283 | |
284 case AUDIO_S16MSB: | |
285 s16src = (Sint16 *) src; | |
286 s16dst = (Sint16 *) dst; | |
287 for (i = 0; i < len; i += sizeof (Sint16), s16src++, s16dst++) | |
288 { | |
289 *s16dst = (Sint16) (((float) (SDL_SwapBE16(*s16src))) * volume); | |
290 *s16dst = SDL_SwapBE16(*s16dst); | |
291 } | |
292 break; | |
293 } | |
294 } | |
295 | |
222 static void audio_callback(void *userdata, Uint8 *stream, int len) | 296 static void audio_callback(void *userdata, Uint8 *stream, int len) |
223 { | 297 { |
224 Sound_Sample *sample = (Sound_Sample *) userdata; | 298 Sound_Sample *sample = (Sound_Sample *) userdata; |
225 int bw = 0; /* bytes written to stream this time through the callback */ | 299 int bw = 0; /* bytes written to stream this time through the callback */ |
226 | 300 |
242 if (cpysize > decoded_bytes) | 316 if (cpysize > decoded_bytes) |
243 cpysize = decoded_bytes; | 317 cpysize = decoded_bytes; |
244 | 318 |
245 if (cpysize > 0) | 319 if (cpysize > 0) |
246 { | 320 { |
247 memcpy(stream + bw, decoded_ptr, cpysize); | 321 memcpy_with_volume(sample, stream + bw, decoded_ptr, cpysize); |
248 bw += cpysize; | 322 bw += cpysize; |
249 decoded_ptr += cpysize; | 323 decoded_ptr += cpysize; |
250 decoded_bytes -= cpysize; | 324 decoded_bytes -= cpysize; |
251 } /* if */ | 325 } /* if */ |
252 } /* while */ | 326 } /* while */ |
362 else if (strcmp(argv[i], "--decodebuf") == 0 && argc > i + 1) | 436 else if (strcmp(argv[i], "--decodebuf") == 0 && argc > i + 1) |
363 { | 437 { |
364 decode_buffersize = atoi(argv[++i]); | 438 decode_buffersize = atoi(argv[++i]); |
365 } /* else if */ | 439 } /* else if */ |
366 | 440 |
441 else if (strcmp(argv[i], "--volume") == 0 && argc > i + 1) | |
442 { | |
443 volume = atof(argv[++i]); | |
444 if (volume != 1.0) | |
445 wants_volume_change = 1; | |
446 } /* else if */ | |
447 | |
367 else if (strcmp(argv[i], "--decoders") == 0) | 448 else if (strcmp(argv[i], "--decoders") == 0) |
368 { | 449 { |
369 if (!Sound_Init()) | 450 if (!Sound_Init()) |
370 { | 451 { |
371 fprintf(stderr, "Sound_Init() failed!\n" | 452 fprintf(stderr, "Sound_Init() failed!\n" |
429 /* !!! FIXME: This is ugly! */ | 510 /* !!! FIXME: This is ugly! */ |
430 if ( (strcmp(argv[i], "--rate") == 0) || | 511 if ( (strcmp(argv[i], "--rate") == 0) || |
431 (strcmp(argv[i], "--format") == 0) || | 512 (strcmp(argv[i], "--format") == 0) || |
432 (strcmp(argv[i], "--channels") == 0) || | 513 (strcmp(argv[i], "--channels") == 0) || |
433 (strcmp(argv[i], "--audiobuf") == 0) || | 514 (strcmp(argv[i], "--audiobuf") == 0) || |
434 (strcmp(argv[i], "--decodebuf") == 0) ) | 515 (strcmp(argv[i], "--decodebuf") == 0) || |
516 (strcmp(argv[i], "--volume") == 0) ) | |
435 { | 517 { |
436 i++; | 518 i++; |
437 continue; | 519 continue; |
438 } /* if */ | 520 } /* if */ |
439 | 521 |