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