comparison playsound/playsound.c @ 308:6a80b2f9c47c

Command line updates, added Darrell to the credits, and cleaned up other stuff. --loop now takes a numeric value.
author Ryan C. Gordon <icculus@icculus.org>
date Wed, 24 Apr 2002 07:56:52 +0000
parents 414cfef0978e
children 9e21cb0d3ae7
comparison
equal deleted inserted replaced
307:eb7c929193dd 308:6a80b2f9c47c
116 " --volume n Playback volume multiplier (default 1.0).\n" 116 " --volume n Playback volume multiplier (default 1.0).\n"
117 " --stdin [ext] Read from stdin (treat data as format [ext])\n" 117 " --stdin [ext] Read from stdin (treat data as format [ext])\n"
118 " --version Display version information and exit.\n" 118 " --version Display version information and exit.\n"
119 " --decoders List supported data formats and exit.\n" 119 " --decoders List supported data formats and exit.\n"
120 " --predecode Decode entire sample before playback.\n" 120 " --predecode Decode entire sample before playback.\n"
121 " --loop Loop playback until SIGINT.\n" 121 " --loop n Loop playback n times. 0=forever.\n"
122
123 /*" --seek list List of seek points and playback durations.\n"*/
124
122 " --credits Shameless promotion.\n" 125 " --credits Shameless promotion.\n"
123 " --help Display this information and exit.\n" 126 " --help Display this information and exit.\n"
124 "\n" 127 "\n"
125 " Valid arguments to the --format option are:\n" 128 " Valid arguments to the --format option are:\n"
126 " U8 Unsigned 8-bit.\n" 129 " U8 Unsigned 8-bit.\n"
127 " S8 Signed 8-bit.\n" 130 " S8 Signed 8-bit.\n"
128 " U16LSB Unsigned 16-bit (least significant byte first).\n" 131 " U16LSB Unsigned 16-bit (least significant byte first).\n"
129 " U16MSB Unsigned 16-bit (most significant byte first).\n" 132 " U16MSB Unsigned 16-bit (most significant byte first).\n"
130 " S16LSB Signed 16-bit (least significant byte first).\n" 133 " S16LSB Signed 16-bit (least significant byte first).\n"
131 " S16MSB Signed 16-bit (most significant byte first).\n" 134 " S16MSB Signed 16-bit (most significant byte first).\n"
135
136 /*
137 "\n"
138 " Valid arguments to the --seek options look like:\n"
139 " --seek=\"mm:ss;mm:ss;mm:ss\"\n"
140 " Where the first \"mm:ss\" is the position, in minutes and\n"
141 " seconds to seek to at start of playback. The second mm:ss\n"
142 " is how long to play audio from that point. The third mm:ss\n"
143 " is another seek after the duration of playback has completed.\n"
144 " If the final playback duration is omitted, playback continues\n"
145 " until the end of the file. --loop and --seek can coexist.\n"
146 */
147
132 "\n", 148 "\n",
133 argv0, DEFAULT_DECODEBUF, DEFAULT_AUDIOBUF); 149 argv0, DEFAULT_DECODEBUF, DEFAULT_AUDIOBUF);
134 } /* output_usage */ 150 } /* output_usage */
135 151
136 152
142 "Public License, and you are welcome to change it and/or\n" 158 "Public License, and you are welcome to change it and/or\n"
143 "distribute copies of it under certain conditions. There is\n" 159 "distribute copies of it under certain conditions. There is\n"
144 "absolutely NO WARRANTY for playsound.\n" 160 "absolutely NO WARRANTY for playsound.\n"
145 "\n" 161 "\n"
146 " Written by Ryan C. Gordon, Torbjörn Andersson, Max Horn,\n" 162 " Written by Ryan C. Gordon, Torbjörn Andersson, Max Horn,\n"
147 " Tsuyoshi Iguchi, Tyler Montbriand, and a cast of thousands.\n" 163 " Tsuyoshi Iguchi, Tyler Montbriand, Darrell Walisser,\n"
164 " and a cast of thousands.\n"
148 "\n" 165 "\n"
149 " Website and source code: http://icculus.org/SDL_sound/\n" 166 " Website and source code: http://icculus.org/SDL_sound/\n"
150 "\n", 167 "\n",
151 PLAYSOUND_VER_MAJOR, PLAYSOUND_VER_MINOR, PLAYSOUND_VER_PATCH); 168 PLAYSOUND_VER_MAJOR, PLAYSOUND_VER_MINOR, PLAYSOUND_VER_PATCH);
152 } /* output_credits */ 169 } /* output_credits */
235 } /* close_archive */ 252 } /* close_archive */
236 253
237 254
238 static void deinit_archive(void) 255 static void deinit_archive(void)
239 { 256 {
240 #if SUPPORT_PHYSFS 257 #if SUPPORT_PHYSFS
241 PHYSFS_deinit(); 258 PHYSFS_deinit();
242 #endif 259 #endif
243 } /* deinit_archive */ 260 } /* deinit_archive */
244 261
245 262
246 263
247 static volatile int done_flag = 0; 264 static volatile int done_flag = 0;
270 done_flag = 1; 287 done_flag = 1;
271 } /* else */ 288 } /* else */
272 } /* sigint_catcher */ 289 } /* sigint_catcher */
273 290
274 291
292 /* global decoding state. */
293 /* !!! FIXME: Put this in a struct and pass a pointer to it as the
294 * !!! FIXME: audio callback's argument. This will clean up the
295 * !!! FIXME: namespace and let me reinitialize this for each file in
296 * !!! FIXME: a cleaner way.
297 */
275 static Uint8 *decoded_ptr = NULL; 298 static Uint8 *decoded_ptr = NULL;
276 static Uint32 decoded_bytes = 0; 299 static Uint32 decoded_bytes = 0;
277 static int predecode = 0; 300 static int predecode = 0;
278 static int looping = 0; 301 static int looping = 0;
279 static int wants_volume_change = 0; 302 static int wants_volume_change = 0;
280 static float volume = 1.0; 303 static float volume = 1.0;
281 304
305
282 /* 306 /*
283 * This updates (decoded_bytes) and (decoder_ptr) with more audio data, 307 * This updates (decoded_bytes) and (decoder_ptr) with more audio data,
284 * taking into account looping and/or predecoding. 308 * taking into account looping and/or predecoding.
285 */ 309 */
286 static int read_more_data(Sound_Sample *sample) 310 static int read_more_data(Sound_Sample *sample)
307 331
308 /* No more to be read from stream, but we may want to loop the sample. */ 332 /* No more to be read from stream, but we may want to loop the sample. */
309 333
310 if (!looping) 334 if (!looping)
311 return(0); 335 return(0);
336
337 looping--;
312 338
313 /* we just need to point predecoded samples to the start of the buffer. */ 339 /* we just need to point predecoded samples to the start of the buffer. */
314 if (predecode) 340 if (predecode)
315 { 341 {
316 decoded_bytes = sample->buffer_size; 342 decoded_bytes = sample->buffer_size;
395 *s16dst = SDL_SwapBE16(*s16dst); 421 *s16dst = SDL_SwapBE16(*s16dst);
396 } 422 }
397 break; 423 break;
398 } 424 }
399 } 425 }
426
400 427
401 static void audio_callback(void *userdata, Uint8 *stream, int len) 428 static void audio_callback(void *userdata, Uint8 *stream, int len)
402 { 429 {
403 Sound_Sample *sample = (Sound_Sample *) userdata; 430 Sound_Sample *sample = (Sound_Sample *) userdata;
404 int bw = 0; /* bytes written to stream this time through the callback */ 431 int bw = 0; /* bytes written to stream this time through the callback */
459 SDL_AudioSpec sdl_actual; 486 SDL_AudioSpec sdl_actual;
460 Sound_Sample *sample; 487 Sound_Sample *sample;
461 int use_specific_audiofmt = 0; 488 int use_specific_audiofmt = 0;
462 int i; 489 int i;
463 int delay; 490 int delay;
491 int new_sample = 1;
464 492
465 setbuf(stdout, NULL); 493 setbuf(stdout, NULL);
466 setbuf(stderr, NULL); 494 setbuf(stderr, NULL);
467 495
468 /* !!! FIXME: Move this to a parse_cmdline() function... */
469 if (argc < 2) 496 if (argc < 2)
470 { 497 {
471 output_usage(argv[0]); 498 output_usage(argv[0]);
472 return(42); 499 return(42);
473 } /* if */ 500 } /* if */
474 501
475 memset(&sound_desired, '\0', sizeof (sound_desired)); 502 /* Check some command lines upfront. */
476
477 for (i = 0; i < argc; i++) 503 for (i = 0; i < argc; i++)
478 { 504 {
479 if (strncmp(argv[i], "--", 2) != 0) 505 if (strncmp(argv[i], "--", 2) != 0)
480 continue; 506 continue;
481 507
494 else if (strcmp(argv[i], "--help") == 0) 520 else if (strcmp(argv[i], "--help") == 0)
495 { 521 {
496 output_usage(argv[0]); 522 output_usage(argv[0]);
497 return(42); 523 return(42);
498 } /* if */ 524 } /* if */
499 525
500 else if (strcmp(argv[i], "--rate") == 0 && argc > i + 1) 526 else if (strcmp(argv[i], "--decoders") == 0)
527 {
528 if (!Sound_Init())
529 {
530 fprintf(stderr, "Sound_Init() failed!\n"
531 " reason: [%s].\n", Sound_GetError());
532 SDL_Quit();
533 return(42);
534 } /* if */
535
536 output_decoders();
537 Sound_Quit();
538 return(0);
539 } /* else if */
540
541 /* !!! FIXME: Verify other --arguments are valid. */
542 #if 0
543 else
544 {
545 fprintf(stderr, "unknown option: \"%s\"\n", argv[i]);
546 return(42);
547 } /* else */
548 #endif
549 } /* for */
550
551 if (!init_archive(argv[0]))
552 return(42);
553
554 if (SDL_Init(SDL_INIT_AUDIO) == -1)
555 {
556 fprintf(stderr, "SDL_Init(SDL_INIT_AUDIO) failed!\n"
557 " reason: [%s].\n", SDL_GetError());
558 return(42);
559 } /* if */
560
561 if (!Sound_Init())
562 {
563 fprintf(stderr, "Sound_Init() failed!\n"
564 " reason: [%s].\n", Sound_GetError());
565 SDL_Quit();
566 return(42);
567 } /* if */
568
569 signal(SIGINT, sigint_catcher);
570
571 for (i = 1; i < argc; i++)
572 {
573 char *filename = NULL;
574
575 /* set variables back to defaults for next file... */
576 if (new_sample)
577 {
578 new_sample = 0;
579 memset(&sound_desired, '\0', sizeof (sound_desired));
580 done_flag = 0;
581 decoded_ptr = NULL;
582 decoded_bytes = 0;
583 predecode = 0;
584 looping = 0;
585 audio_buffersize = DEFAULT_AUDIOBUF;
586 decode_buffersize = DEFAULT_DECODEBUF;
587 sample = NULL;
588 use_specific_audiofmt = 0;
589 wants_volume_change = 0;
590 volume = 1.0;
591 } /* if */
592
593 if (strcmp(argv[i], "--rate") == 0 && argc > i + 1)
501 { 594 {
502 use_specific_audiofmt = 1; 595 use_specific_audiofmt = 1;
503 sound_desired.rate = atoi(argv[++i]); 596 sound_desired.rate = atoi(argv[++i]);
504 if (sound_desired.rate <= 0) 597 if (sound_desired.rate <= 0)
505 { 598 {
548 volume = atof(argv[++i]); 641 volume = atof(argv[++i]);
549 if (volume != 1.0) 642 if (volume != 1.0)
550 wants_volume_change = 1; 643 wants_volume_change = 1;
551 } /* else if */ 644 } /* else if */
552 645
553 else if (strcmp(argv[i], "--decoders") == 0)
554 {
555 if (!Sound_Init())
556 {
557 fprintf(stderr, "Sound_Init() failed!\n"
558 " reason: [%s].\n", Sound_GetError());
559 SDL_Quit();
560 return(42);
561 } /* if */
562
563 output_decoders();
564 Sound_Quit();
565 return(0);
566 } /* else if */
567
568 else if (strcmp(argv[i], "--predecode") == 0) 646 else if (strcmp(argv[i], "--predecode") == 0)
569 { 647 {
570 predecode = 1; 648 predecode = 1;
571 } /* else if */ 649 } /* else if */
572 650
573 else if (strcmp(argv[i], "--loop") == 0) 651 else if (strcmp(argv[i], "--loop") == 0)
574 { 652 {
575 looping = 1; 653 looping = atoi(argv[++i]);
576 } /* else if */ 654 } /* else if */
577 655
578 else if (strcmp(argv[i], "--stdin") == 0) 656 else if (strcmp(argv[i], "--stdin") == 0)
579 {
580 /* deal with it at Sound_Sample creation time... */
581 } /* else if */
582
583 else
584 {
585 fprintf(stderr, "unknown option: \"%s\"\n", argv[i]);
586 return(42);
587 } /* else */
588 } /* for */
589
590 /* Pick sensible defaults for any value not explicitly specified. */
591 if (use_specific_audiofmt)
592 {
593 if (sound_desired.rate == 0)
594 sound_desired.rate = 44100;
595 if (sound_desired.format == 0)
596 sound_desired.format = AUDIO_S16SYS;
597 if (sound_desired.channels == 0)
598 sound_desired.channels = 2;
599 } /* if */
600
601 if (!init_archive(argv[0]))
602 return(42);
603
604 if (SDL_Init(SDL_INIT_AUDIO) == -1)
605 {
606 fprintf(stderr, "SDL_Init(SDL_INIT_AUDIO) failed!\n"
607 " reason: [%s].\n", SDL_GetError());
608 return(42);
609 } /* if */
610
611 if (!Sound_Init())
612 {
613 fprintf(stderr, "Sound_Init() failed!\n"
614 " reason: [%s].\n", Sound_GetError());
615 SDL_Quit();
616 return(42);
617 } /* if */
618
619 signal(SIGINT, sigint_catcher);
620
621 for (i = 1; i < argc; i++)
622 {
623 char *filename = NULL;
624
625 /* !!! FIXME: This is ugly! */
626 if ( (strcmp(argv[i], "--rate") == 0) ||
627 (strcmp(argv[i], "--format") == 0) ||
628 (strcmp(argv[i], "--channels") == 0) ||
629 (strcmp(argv[i], "--audiobuf") == 0) ||
630 (strcmp(argv[i], "--decodebuf") == 0) ||
631 (strcmp(argv[i], "--volume") == 0) )
632 {
633 i++;
634 continue;
635 } /* if */
636
637 if (strcmp(argv[i], "--stdin") == 0)
638 { 657 {
639 SDL_RWops *rw = SDL_RWFromFP(stdin, 1); 658 SDL_RWops *rw = SDL_RWFromFP(stdin, 1);
640 filename = "...from stdin..."; 659 filename = "...from stdin...";
641 660
642 /* 661 /*
647 use_specific_audiofmt ? &sound_desired : NULL, 666 use_specific_audiofmt ? &sound_desired : NULL,
648 decode_buffersize); 667 decode_buffersize);
649 } /* if */ 668 } /* if */
650 669
651 else if (strncmp(argv[i], "--", 2) == 0) 670 else if (strncmp(argv[i], "--", 2) == 0)
652 { 671 /* ignore it. */ ;
653 continue;
654 } /* else if */
655 672
656 else 673 else
657 { 674 {
658 filename = argv[i]; 675 filename = argv[i];
659 sample = sample_from_archive(filename, 676 sample = sample_from_archive(filename,
666 use_specific_audiofmt ? &sound_desired : NULL, 683 use_specific_audiofmt ? &sound_desired : NULL,
667 decode_buffersize); 684 decode_buffersize);
668 } /* if */ 685 } /* if */
669 } /* else */ 686 } /* else */
670 687
671 if (!sample) 688 if (filename == NULL) /* still parsing command line stuff? */
689 continue;
690
691 new_sample = 1;
692
693 if (sample == NULL)
672 { 694 {
673 fprintf(stderr, "Couldn't load \"%s\"!\n" 695 fprintf(stderr, "Couldn't load \"%s\"!\n"
674 " reason: [%s].\n", filename, Sound_GetError()); 696 " reason: [%s].\n",
697 filename, Sound_GetError());
675 continue; 698 continue;
676 } /* if */ 699 } /* if */
677 700
678 /* 701 /*
679 * Unless explicitly specified, pick the format from the sound 702 * Unless explicitly specified, pick the format from the sound
680 * to be played. 703 * to be played.
681 */ 704 */
682 if (use_specific_audiofmt) 705 if (use_specific_audiofmt)
683 { 706 {
707 /* Pick sensible default for any value not explicitly specified. */
708 if (sound_desired.rate == 0)
709 sound_desired.rate = 44100;
710 if (sound_desired.format == 0)
711 sound_desired.format = AUDIO_S16SYS;
712 if (sound_desired.channels == 0)
713 sound_desired.channels = 2;
714
684 sdl_desired.freq = sound_desired.rate; 715 sdl_desired.freq = sound_desired.rate;
685 sdl_desired.format = sound_desired.format; 716 sdl_desired.format = sound_desired.format;
686 sdl_desired.channels = sound_desired.channels; 717 sdl_desired.channels = sound_desired.channels;
687 } /* if */ 718 } /* if */
688 else 719 else
724 { 755 {
725 printf("done.\n"); 756 printf("done.\n");
726 } /* else */ 757 } /* else */
727 } /* if */ 758 } /* if */
728 759
729 done_flag = 0;
730 SDL_PauseAudio(0); 760 SDL_PauseAudio(0);
731 while (!done_flag) 761 while (!done_flag)
732 { 762 {
733 SDL_Delay(10); 763 SDL_Delay(10);
734 } /* while */ 764 } /* while */