comparison playsound/playsound.c @ 222:d6b24586822a

Support for looping sounds via a new --loop command line. Rewritten (again!) audio callback.
author Ryan C. Gordon <icculus@icculus.org>
date Thu, 17 Jan 2002 20:54:46 +0000
parents e27b33a6d5fe
children 034b2e56f405
comparison
equal deleted inserted replaced
221:c9772a9f5271 222:d6b24586822a
107 " --decodebuf n Buffer n decoded bytes at a time (default %d).\n" 107 " --decodebuf n Buffer n decoded bytes at a time (default %d).\n"
108 " --audiobuf n Buffer n samples to audio device (default %d).\n" 108 " --audiobuf n Buffer n samples to audio device (default %d).\n"
109 " --version Display version information and exit.\n" 109 " --version Display version information and exit.\n"
110 " --decoders List supported data formats and exit.\n" 110 " --decoders List supported data formats and exit.\n"
111 " --predecode Decode entire sample before playback.\n" 111 " --predecode Decode entire sample before playback.\n"
112 " --loop Loop playback until SIGINT.\n"
112 " --credits Shameless promotion.\n" 113 " --credits Shameless promotion.\n"
113 " --help Display this information and exit.\n" 114 " --help Display this information and exit.\n"
114 "\n" 115 "\n"
115 " Valid arguments to the --format option are:\n" 116 " Valid arguments to the --format option are:\n"
116 " U8 Unsigned 8-bit.\n" 117 " U8 Unsigned 8-bit.\n"
170 } /* sigint_catcher */ 171 } /* sigint_catcher */
171 172
172 173
173 static Uint8 *decoded_ptr = NULL; 174 static Uint8 *decoded_ptr = NULL;
174 static Uint32 decoded_bytes = 0; 175 static Uint32 decoded_bytes = 0;
176 static int predecode = 0;
177 static int looping = 0;
178
179 /*
180 * This updates (decoded_bytes) and (decoder_ptr) with more audio data,
181 * taking into account looping and/or predecoding.
182 */
183 static int read_more_data(Sound_Sample *sample)
184 {
185 if (done_flag) /* probably a sigint; stop trying to read. */
186 decoded_bytes = 0;
187
188 if (decoded_bytes > 0) /* don't need more data; just return. */
189 return(decoded_bytes);
190
191 /* need more. See if there's more to be read... */
192 if (!(sample->flags & (SOUND_SAMPLEFLAG_ERROR | SOUND_SAMPLEFLAG_EOF)))
193 {
194 decoded_bytes = Sound_Decode(sample);
195 decoded_ptr = sample->buffer;
196 return(read_more_data(sample)); /* handle loops conditions. */
197 } /* if */
198
199 /* No more to be read from stream, but we may want to loop the sample. */
200
201 if (!looping)
202 return(0);
203
204 /* we just need to point predecoded samples to the start of the buffer. */
205 if (predecode)
206 {
207 decoded_bytes = sample->buffer_size;
208 decoded_ptr = sample->buffer;
209 return(decoded_bytes);
210 } /* if */
211 else
212 {
213 Sound_Rewind(sample); /* error is checked in recursion. */
214 return(read_more_data(sample));
215 } /* else */
216
217 assert(0); /* shouldn't ever hit this point. */
218 return(0);
219 } /* read_more_data */
220
175 221
176 static void audio_callback(void *userdata, Uint8 *stream, int len) 222 static void audio_callback(void *userdata, Uint8 *stream, int len)
177 { 223 {
178 Sound_Sample *sample = (Sound_Sample *) userdata; 224 Sound_Sample *sample = (Sound_Sample *) userdata;
179 int bw = 0; /* bytes written to stream this time through the callback */ 225 int bw = 0; /* bytes written to stream this time through the callback */
180 226
181 while (bw < len) 227 while (bw < len)
182 { 228 {
183 int cpysize; /* bytes to copy on this iteration of the loop. */ 229 int cpysize; /* bytes to copy on this iteration of the loop. */
184 230
185 if (!decoded_bytes) /* need more data decoded from sample? */ 231 if (!read_more_data(sample)) /* read more data, if needed. */
186 { 232 {
187 if (sample->flags & (SOUND_SAMPLEFLAG_ERROR|SOUND_SAMPLEFLAG_EOF)) 233 /* ...there isn't any more data to read! */
188 { 234 memset(stream + bw, '\0', len - bw);
189 /* ...but there isn't any more data to decode! */ 235 done_flag = 1;
190 memset(stream + bw, '\0', len - bw); 236 return;
191 done_flag = 1; 237 } /* if */
192 return; 238
193 } /* if */ 239 /* decoded_bytes and decoder_ptr are updated as necessary... */
194
195 decoded_bytes = Sound_Decode(sample);
196 decoded_ptr = sample->buffer;
197 } /* if */
198 240
199 cpysize = len - bw; 241 cpysize = len - bw;
200 if (cpysize > decoded_bytes) 242 if (cpysize > decoded_bytes)
201 cpysize = decoded_bytes; 243 cpysize = decoded_bytes;
202 244
235 Uint32 audio_buffersize = DEFAULT_AUDIOBUF; 277 Uint32 audio_buffersize = DEFAULT_AUDIOBUF;
236 Uint32 decode_buffersize = DEFAULT_DECODEBUF; 278 Uint32 decode_buffersize = DEFAULT_DECODEBUF;
237 SDL_AudioSpec sdl_desired; 279 SDL_AudioSpec sdl_desired;
238 SDL_AudioSpec sdl_actual; 280 SDL_AudioSpec sdl_actual;
239 Sound_Sample *sample; 281 Sound_Sample *sample;
240 int predecode = 0;
241 int use_specific_audiofmt = 0; 282 int use_specific_audiofmt = 0;
242 int i; 283 int i;
243 int delay; 284 int delay;
244 285
245 setbuf(stdout, NULL); 286 setbuf(stdout, NULL);
339 } /* else if */ 380 } /* else if */
340 381
341 else if (strcmp(argv[i], "--predecode") == 0) 382 else if (strcmp(argv[i], "--predecode") == 0)
342 { 383 {
343 predecode = 1; 384 predecode = 1;
385 } /* else if */
386
387 else if (strcmp(argv[i], "--loop") == 0)
388 {
389 looping = 1;
344 } /* else if */ 390 } /* else if */
345 391
346 else 392 else
347 { 393 {
348 fprintf(stderr, "unknown option: \"%s\"\n", argv[i]); 394 fprintf(stderr, "unknown option: \"%s\"\n", argv[i]);