home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / MM1 / SOUNDUTILS / audioplay.lzh / AUDIOPLAY / SRC / auplay.c < prev    next >
Text File  |  1995-03-29  |  5KB  |  251 lines

  1. /* auplay.c - play NeXT/Sun *.au file on MM/1 - Andrzej Kotanski 1994 */
  2.  
  3. #include "play.h"
  4. #include "audio_filehdr.h"
  5. #include "ulaw.h"
  6.  
  7. static Audio_filehdr hdr;
  8. static char title[100];
  9. static char *buf1, *buf2, *buf;
  10. char *malloc();
  11.  
  12. static char *Encoding[] = {
  13.     "Not Set",
  14.     "8 Bit U-Law",
  15.     "8 Bit Linear",
  16.     "16 Bit Linear",
  17.     "24 Bit Linear",
  18.     "32 Bit Linear",
  19.     "Encoded IEEE Float",
  20.     "Encoded IEEE Double"
  21. };
  22.  
  23. auplay(fd)
  24. path_id fd;
  25. {
  26.     u_int32 res, sleepTime;
  27.     u_int inverted;
  28.     unsigned char ch;
  29.  
  30.     size = sizeof(hdr);
  31.  
  32.     if ((read(fd, &hdr, size)) == -1) {
  33.         cleanup(errno, "cannot read header");
  34.     }
  35.  
  36.     if (hdr.magic == DecDiva)
  37.     {
  38.         lseek(fd,0xa5,SEEK_SET);
  39.         read(fd, &ch, 1);
  40.         lseek(fd,0x26 + ch,SEEK_SET);
  41.  
  42.         if ((read(fd, &hdr, size)) == -1) {
  43.             cleanup(errno, "cannot read header");
  44.         }
  45.     } 
  46.  
  47.     switch(hdr.magic) {
  48.         case MagicSun:
  49.         case MagicDec:
  50.             inverted = FALSE;
  51.             break;
  52.         case MagicSunI:
  53.         case MagicDecI:
  54.             inverted = TRUE;
  55.             swab4(&hdr.hdr_size);
  56.             swab4(&hdr.data_size);   /* data size */
  57.             swab4(&hdr.encoding);    /* encoding */
  58.             swab4(&hdr.sample_rate); /* sample rate */
  59.             swab4(&hdr.channels);    /* number of channels */
  60.             break;
  61.         default:
  62.             cleanup(0, "bad magic number");
  63.     }
  64.  
  65.     size = hdr.hdr_size - sizeof(hdr);
  66.     if ((read(fd, title, size)) == -1) {
  67.         cleanup(errno, "cannot read header");
  68.     }
  69.  
  70.     if ( hdr.encoding < AUDIO_FILE_ENCODING_MULAW_8
  71.         || hdr.encoding > AUDIO_FILE_ENCODING_DOUBLE ) {
  72.         cleanup(0, "encoding type uknown");
  73.     }
  74.     if ( hdr.channels != 1 && hdr.channels != 2 ) {
  75.         cleanup(0, "invalid number of channels");
  76.     }
  77.  
  78.     if (!quiet) {
  79.         fprintf(stderr, "Title: %s\n", title);
  80.         fprintf(stderr, "Length: %d\n", hdr.data_size);
  81.         fprintf(stderr, "Sample rate: %d\n", hdr.sample_rate);
  82.         fprintf(stderr, "Channels: %d\n", hdr.channels);
  83.         fprintf(stderr, "Encoding: %s\n", Encoding[hdr.encoding]);
  84.     }
  85.  
  86.     if ( hdr.encoding > AUDIO_FILE_ENCODING_LINEAR_16) {
  87.         cleanup(0, "cannot decode this type of encoding");
  88.     }
  89.  
  90.     if (hdr.channels == 1) {
  91.         buf1 = malloc(bufferSize*2);
  92.         buf2 = malloc(bufferSize*2);
  93.     } else {
  94.         buf1 = malloc(bufferSize);
  95.         buf2 = malloc(bufferSize);
  96.     }
  97.  
  98.     if (buf1 == NULL || buf2 == NULL) {
  99.         cleanup(errno, "cannot allocate memory");
  100.     }
  101.  
  102.     buf = buf2;
  103.     sigarrived = 1;
  104.  
  105.     do {
  106.         buf = buf == buf1 ? buf2 : buf1;
  107.  
  108.         res = (hdr.data_size > bufferSize) ? bufferSize : hdr.data_size;
  109.         if ((read(fd, buf, res)) != res) {
  110.             hdr.data_size = 0;
  111. #if 0
  112.             if (errno == E_EOF) {
  113.                 break;
  114.             } else {
  115.                 cleanup(errno, "cannot read file");
  116.             }
  117. #endif
  118.         }
  119.         else
  120.             hdr.data_size -= res;
  121.  
  122.         if ( hdr.encoding == AUDIO_FILE_ENCODING_LINEAR_16) {
  123.             res >>= 1;
  124.             crunch(buf,res,inverted);
  125.         }
  126.  
  127.         if ( hdr.channels == 2 ) {
  128.             if (hdr.encoding == AUDIO_FILE_ENCODING_MULAW_8)
  129.                 process(buf, res);
  130.         } else {
  131.             process1(buf, res, hdr.encoding);
  132.         }
  133.  
  134.         if ( sigarrived == 0) {
  135.             sleepTime = 0;
  136.             tsleep(sleepTime);
  137.         }
  138.         sigarrived = 0;
  139.  
  140.         _ss_play(1, buf, hdr.channels == 1 ? res*2 : res,
  141.             hdr.sample_rate, SND_SENDSIG, SIG_CODE);
  142.  
  143.     } while ( hdr.data_size > 0 );
  144.  
  145.     sleepTime = 0;
  146.     tsleep(sleepTime);
  147.  
  148.     /* free up our memory */
  149.     free(buf1);
  150.     free(buf2);
  151.     close(fd);
  152. }
  153.  
  154. static process(buf, n)
  155. unsigned char *buf;
  156. int n;
  157. {
  158.     u_int32 i;
  159.  
  160.     for ( i = 0; i < n ; i++ ) {
  161.         buf[i] = ulaw_to_byte_linear(buf[i] & 0xFF);
  162.     }
  163. }
  164.  
  165. static process1(buf, n, encoding)
  166. char *buf;
  167. int n;
  168. int encoding;
  169. {
  170.     int32 i;
  171.  
  172.     if (hdr.encoding == AUDIO_FILE_ENCODING_MULAW_8) {
  173.         for (i = n - 1; i >= 0 ; i--) {
  174.             buf[2*i + 1] = buf[2*i] = ulaw_to_byte_linear(buf[i] & 0xFF);
  175.         }
  176.     } else {
  177.         for (i = n - 1; i >= 0 ; i--) {
  178.             buf[2*i + 1] = buf[2*i] = buf[i];
  179.         }
  180.     }
  181. }
  182.  
  183. static crunch(buf, n, inv)
  184. unsigned char *buf;
  185. int n;
  186. int inv;
  187. {
  188.     u_int32 i;
  189.     unsigned short *src = (unsigned short *)buf;
  190.  
  191.     if (inv) {
  192.         for ( i = 0; i < n ; i++ ) {
  193.             buf[i] = src[i] & 0xFF;
  194.         }
  195.     } else {
  196.         for ( i = 0; i < n ; i++ ) {
  197.             buf[i] = (src[i] >> 8) & 0xFF;
  198.         }
  199.     }
  200. }
  201.  
  202.  
  203. #if 0
  204. /*
  205. ** This routine converts from ulaw to 16 bit linear.
  206. **
  207. ** Craig Reese: IDA/Supercomputing Research Center
  208. ** 29 September 1989
  209. **
  210. ** References:
  211. ** 1) CCITT Recommendation G.711  (very difficult to follow)
  212. ** 2) MIL-STD-188-113,"Interoperability and Performance Standards
  213. **     for Analog-to_Digital Conversion Techniques,"
  214. **     17 February 1987
  215. **
  216. ** Input: 8 bit ulaw sample
  217. ** Output: signed 16 bit linear sample
  218. */
  219.  
  220. static int ulaw2linear(ulawbyte)
  221. register unsigned char ulawbyte;
  222. {
  223.     static int exp_lut[8] = { 0, 132, 396, 924, 1980, 4092, 8316, 16764 };
  224.     register int sign, exponent, mantissa, sample;
  225.  
  226.     ulawbyte = ~ulawbyte;
  227.     sign = (ulawbyte & 0x80);
  228.     exponent = (ulawbyte >> 4) & 0x07;
  229.     mantissa = ulawbyte & 0x0F;
  230.     sample = exp_lut[exponent] + (mantissa << (exponent + 3));
  231.     if (sign != 0) sample = -sample;
  232.  
  233.     return(sample >> 8);
  234. }
  235. #endif
  236.  
  237. static swab4(x)
  238. register unsigned short *x;
  239. {
  240.     register unsigned char a, b, c, d;
  241.  
  242.     a = *(unsigned char *) x;
  243.     b = *((unsigned char *) x + 1);
  244.     c = *((unsigned char *) x + 2);
  245.     d = *((unsigned char *) x + 3);
  246.     *(unsigned char *) x = d;
  247.     *((unsigned char *) x + 1) = c;
  248.     *((unsigned char *) x + 2) = b;
  249.     *((unsigned char *) x + 3) = a;
  250. }
  251.