home *** CD-ROM | disk | FTP | other *** search
/ ftp.4front-tech.com / ftp.4front-tech.com.tar / ftp.4front-tech.com / ossfree / snd-util-3.8.tar.gz / snd-util-3.8.tar / sndkit / dsp / str / str.c < prev    next >
C/C++ Source or Header  |  1997-12-08  |  7KB  |  268 lines

  1. /************************************************************************/
  2. /*                                    */
  3. /* str.c - plays sound-/noisetracker files on a SparcStation        */
  4. /*                                    */
  5. /* Authors:                                */
  6. /*        Liam Corner - zenith@dcs.warwick.ac.uk            */
  7. /*        Marc Espie - espie@dmi.ens.fr                */
  8. /* Minor modificatios for Linux by                    */
  9. /*        Hannu Savolainen - hannu@opensound.com            */
  10. /* Command-line switches added by                    */
  11. /*        Muhammad Saggaf - alsaggaf@erl.mit.edu            */
  12. /*        Leif Kornstaedt - l_kornst@informatik.uni-kl.de        */
  13. /* Relaxed program name checking                    */
  14. /*        Craig Metz - cmetz@thor.tjhsst.edu                */
  15. /* Stereo and 16 bit support by                        */
  16. /*        Hannu                            */
  17. /* Some effects and minor bugfixes/ameliorations by            */
  18. /*        Leif Kornstaedt - l_kornst@informatik.uni-kl.de        */
  19. /*                                    */
  20. /* Version: 1.20 - 3 November 1991 / 31 January 1993            */
  21. /* 01/31/93 effects added                        */
  22. /*        by Leif Kornstaedt                        */
  23. /* 08/27/92 modified to use integer arithmetic                */
  24. /* 08/31/92 SB Pro stereo support                    */
  25. /*        by Hannu Savolainen                        */
  26. /*                                    */
  27. /************************************************************************/
  28.  
  29. #include <stdio.h>
  30. #include <malloc.h>
  31. #include <unistd.h>
  32. #include <stdlib.h>
  33. #ifdef __STDC__
  34. #include <fcntl.h>
  35. #include <string.h>
  36. #else /* __STDC__ */
  37. #include <getopt.h>
  38. #include <fcntl.h>
  39. #include <strings.h>
  40. #endif /* __STDC__ */
  41. #include <errno.h>
  42. #include <sys/stat.h>
  43.  
  44. #include <sys/soundcard.h>
  45. #include "str.h"
  46.  
  47. /* output file name or dsp device */
  48. char AUDIO[256] = AUDIONAME;
  49.  
  50. int audio;            /* file handle */
  51. unsigned char *audiobuf;
  52. int abuf_size;
  53. int abuf_ptr;
  54.  
  55. /* for analyzing the command line: */
  56. char *command;            /* the actual command name used (argv[0]) */
  57. int loop_forever = FALSE;
  58. int quiet_mode = FALSE, verbose_mode = FALSE;
  59. static int use_zcat = FALSE;
  60. int mute[4] = { FALSE, FALSE, FALSE, FALSE };
  61. int dsp_stereo = DSP_DEFAULT_STEREO;
  62. int dsp_samplesize = DSP_DEFAULT_SAMPLESIZE;
  63. long dsp_speed = DEFAULT_DSP_SPEED;
  64.  
  65. FILE *fp;
  66.  
  67. void play_song(void);
  68. extern void describe_error(void); /* from ../help.c */
  69.  
  70. void
  71. usage(command)
  72. char *command;
  73. {
  74.     fprintf(stderr, "Usage: %s [ -cqvzS1234 -b size -s kHz -o output_file ] "
  75.         "[ filename ... ]\n", command);
  76.     fprintf(stderr, "\t-c\t\tplay infinitely\n"
  77.             "\t-q\t\tquiet mode\n"
  78.             "\t-v\t\tverbose mode\n"
  79.             "\t-z\t\tuse zcat on file\n"
  80.             "\t-1234\t\tmute voices 1, 2, 3 or 4\n"
  81.             "\t-S\t\ttoggle stereo\n"
  82.             "\t-b size\t\tset sample size (8 or 16 bits)\n"
  83.             "\t-s kHz\t\tuse sampling speed kHz\n"
  84.             "\t-o file\t\tredirect output to a file\n");
  85.      exit(EXIT_FAILURE);
  86. }
  87.  
  88. char *
  89. find_file(name)
  90. char *name;
  91. {
  92.     char *dirs;
  93.     struct stat statbuffer;
  94.     static char fname[256];
  95.  
  96.     strcpy(fname, name);
  97.     if(stat(fname, &statbuffer) != -1 && errno != -ENOENT)
  98.     return fname;
  99.     else {
  100.     dirs = getenv("MODPATH");
  101.     while(dirs != NULL && strlen(dirs)) {
  102.         if(strchr(dirs, ':') != NULL) {
  103.         strncpy(fname, dirs, strchr(dirs, ':') - dirs);
  104.         fname[strchr(dirs, ':') - dirs] = '\0';
  105.         } else
  106.         strcpy(fname, dirs);
  107.         if(fname[strlen(fname) - 1] != '/')
  108.         strcat(fname, "/");
  109.         strcat(fname, name);
  110.         if(stat(fname, &statbuffer) != -1 && errno != -ENOENT)
  111.         return fname;
  112.         if((dirs = strchr(dirs, ':')) != NULL)
  113.         dirs++;
  114.     }
  115.     }
  116.  
  117.     return NULL;
  118. }
  119.  
  120. int 
  121. main(argc, argv)
  122. int argc;
  123. char *argv[];
  124. {
  125.     int outdev, c;
  126.     struct stat statbuffer;
  127.     int opmode = O_WRONLY;        /* mode for opening the output device */
  128.     char zcat_cmd[256];
  129.     char *currfile;
  130.  
  131.     command = argv[0];
  132.  
  133.     while((c = getopt(argc, argv,
  134.                   "cqvz1234Sb:s:o:"
  135.                           )) != EOF)
  136.     switch(c) {
  137.     case 'c':            /* play infinitely */
  138.         loop_forever = TRUE;
  139.         break;
  140.     case 'q':            /* quiet mode */
  141.         quiet_mode = TRUE;
  142.         break;
  143.     case 'v':            /* verbose mode */
  144.         verbose_mode = TRUE;
  145.         break;
  146.     case 'z':            /* use zcat on file */
  147.         use_zcat = TRUE;
  148.         break;
  149.     case '1':
  150.     case '2':
  151.     case '3':
  152.     case '4':
  153.         mute[c - '1'] = TRUE;
  154.         break;
  155.     case 'S':            /* toggle stereo */
  156.         dsp_stereo = !DSP_DEFAULT_STEREO;
  157.         break;
  158.     case 'b':            /* sample size */
  159.         dsp_samplesize = atoi(optarg);
  160.         break;
  161.     case 's':            /* dsp speed */
  162.         dsp_speed = atoi(optarg);
  163.         if(dsp_speed < 300)
  164.         dsp_speed *= 1000;
  165.         break;
  166.     case 'o':            /* output file */
  167.         strcpy(AUDIO, optarg);
  168.         break;
  169.     default:
  170.         usage(command);
  171.     }
  172.  
  173.     /* output to a character device (TRUE) or a file (FALSE)? */
  174.     outdev = !stat(AUDIO, &statbuffer) && S_ISCHR(statbuffer.st_mode);
  175.  
  176.     if(!outdev)
  177.     opmode |= O_CREAT;        /* file: create it */
  178.     if((audio = open(AUDIO, opmode, 0)) == -1) {
  179.     perror(AUDIO);
  180.     describe_error();
  181.     exit(EXIT_FAILURE);
  182.     }
  183.  
  184.  
  185.     if(outdev) {            /* set dsp parameters */
  186.     if(ioctl(audio, SNDCTL_DSP_SAMPLESIZE,
  187.         &dsp_samplesize) == -1)
  188.         dsp_samplesize = 8;
  189.     if(ioctl(audio, SNDCTL_DSP_STEREO, &dsp_stereo) == -1)
  190.         dsp_stereo = FALSE;
  191.     if(ioctl(audio, SNDCTL_DSP_SPEED, &dsp_speed) == -1) {
  192.         fprintf(stderr, "%s: unable to set playback speed\n", command);
  193.         perror(AUDIO);
  194.         exit(EXIT_FAILURE);
  195.     }
  196.     if(!quiet_mode)
  197.         printf("Playback speed %d Hz (%s) %d bits/sample.\n", dsp_speed,
  198.             dsp_stereo? "stereo": "mono", dsp_samplesize);
  199.     }
  200.  
  201.     if(outdev) {            /* get the dsp buffer size */
  202.     ioctl(audio, SNDCTL_DSP_GETBLKSIZE, &abuf_size);
  203.     if(abuf_size < 1) {
  204.          perror("audio_size");
  205.         close(audio);
  206.         exit(EXIT_FAILURE);
  207.     }
  208.     } else {                /* to a file: use block size of 1kB */
  209.     abuf_size = 1024;
  210.     loop_forever = 0;
  211.     }
  212.  
  213.     if((audiobuf = malloc(abuf_size)) == NULL) {
  214.     fprintf(stderr, "%s: unable to allocate output buffer\n", command);
  215.     close(audio);
  216.     exit(EXIT_FAILURE);
  217.     }
  218.     abuf_ptr = 0;
  219.  
  220.     if(optind > argc - 1) {
  221.     if(use_zcat) {
  222.         if((fp = popen(ZCAT, "rb")) == NULL) {
  223.         fprintf(stderr, "%s: can't execute " ZCAT ".\n", command);
  224.         return(EXIT_FAILURE);
  225.         }
  226.     } else
  227.         fp = stdin;
  228.     play_song();
  229.     if(use_zcat)
  230.         pclose(fp);
  231.     } else
  232.     while(optind <= argc - 1)
  233.         if((currfile = find_file(argv[optind])) == NULL) {
  234.         fprintf(stderr, "%s: can't find file %s - skipping.\n",
  235.             command, argv[optind]);
  236.         optind++;
  237.         } else if(use_zcat) {
  238.         if((fp = popen(strcat(strcpy(zcat_cmd, ZCAT " "),
  239.             currfile), "rb")) == NULL) {
  240.             fprintf(stderr, "%s: can't execute " ZCAT " %s.\n",
  241.                 command, currfile);
  242.             exit(EXIT_FAILURE);
  243.         } else {
  244.             play_song();
  245.             pclose(fp);
  246.             if(!loop_forever)
  247.             optind++;
  248.         }
  249.         } else {
  250.         if((fp = fopen(currfile, "rb")) == NULL) {
  251.             fprintf(stderr, "%s: unable to open tune file %s.\n",
  252.                 command, currfile);
  253.             exit(EXIT_FAILURE);
  254.         } else {
  255.             play_song();
  256.             fclose(fp);
  257.             if(!loop_forever)
  258.             optind++;
  259.         }
  260.         }
  261.  
  262.     if(abuf_ptr)
  263.     write(audio, audiobuf, abuf_ptr);
  264.     close(audio);
  265.  
  266.     return EXIT_SUCCESS;
  267. }
  268.