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 / vocplay.c < prev    next >
Text File  |  1995-03-28  |  8KB  |  376 lines

  1. /* vocplay.c - play Creative Voice *.voc file on MM/1 - Andrzej Kotanski 1994 */
  2.  
  3. #include "play.h"
  4.  
  5.  
  6. static struct head {
  7.    char magic[20];
  8.    short offset;
  9.    short version;
  10.    short version2;
  11. } hdr;
  12.  
  13. static unsigned char hdr2[10];
  14.  
  15. static char type;
  16. static unsigned char *buf1, *buf2, *buf, hd[2];
  17. unsigned char *malloc();
  18. static int sample_rate, data_size;
  19. static int channels = 1;
  20. static u_int32 sleepTime;
  21. static char comment[80];
  22.  
  23. enum types { Terminator, Sound_data, Sound_continue, Silence, Marker,
  24.              ASCII, Repeat, End_repeat, Extended };
  25.  
  26. void vocplay(fd)
  27. path_id fd;
  28. {
  29.     int  res;
  30.     int  repeat;
  31.     long loop_pos, lseek();
  32.     int  sig_pending = 0;
  33.     int  comp_type;
  34.     int  got_extended = FALSE;
  35.  
  36.     size = sizeof(hdr);
  37.     sample_rate = 0;
  38.     if (read(fd, &hdr, size) == -1) {
  39.         cleanup(errno, "cannot read header");
  40.     }
  41.  
  42.     if (strncmp(hdr.magic, "Creative Voice File\x1a", 20)) {
  43.         cleanup(0, "bad header title !");
  44.     }
  45.  
  46.     if (hdr.version + hdr.version2 != 0x3312) {
  47.         if (!quiet) {
  48.             fprintf(stderr, "bad header checksum - trying to play anyway\n");
  49.         }
  50.     }
  51.     hdr.offset = swab(&hdr.offset);
  52.  
  53.     /* reposition our to first data block */
  54.     if (lseek(fd,hdr.offset,SEEK_SET) == -1)
  55.         cleanup(errno, "cannot seek to first datablock");
  56.  
  57.     /* allocate out buffers once...
  58.      *   there may be more than one sample or we might have to loop.
  59.      */
  60.     buf1 = malloc(bufferSize*2);
  61.     buf2 = malloc(bufferSize*2);
  62.  
  63.     if (buf1 == NULL || buf2 == NULL) {
  64.         cleanup(errno, "cannot allocate buffer");
  65.     }
  66.  
  67.     /* point to one of the buffers */
  68.     buf = buf2;
  69.  
  70.     /* set out signal flag to true for first time through */
  71.     sigarrived = 1;
  72.  
  73.     for (;;) {
  74.         size = 1;
  75.         if ((read(fd, &type, size)) == -1) {
  76.             if (errno == E_EOF) {
  77.                 close(fd);
  78.                 return;
  79.             } else {
  80.                 cleanup(errno, "cannot read header2");
  81.             }
  82.         }
  83.  
  84.         if (debug)
  85.             printf("type = %d\n",type);
  86.         /* extended lasts only if next block is sound */
  87.         if (got_extended == TRUE && type != Sound_data)
  88.             got_extended = FALSE;
  89.  
  90.         switch (type) {
  91.             case Terminator:
  92.                 /* let's wait till the sound has been played before
  93.                  * we deallocate the memory on _ss_play(). It's the
  94.                  * polite thing to do. :)
  95.                  */
  96.                 if (sig_pending)
  97.                 {
  98.                     while (! sigarrived)
  99.                         tsleep(0);
  100.                     sig_pending = 0;
  101.                 }
  102.                 /* deallocate out buffers */
  103.                 free(buf1);
  104.                 free(buf2);
  105.                 close(fd);
  106.                 return;
  107.  
  108.             case Silence:
  109.                 size = 6;
  110.                 if ((read(fd, hdr2, size)) == -1) {
  111.                     cleanup(errno, "cannot read header2");
  112.                 }
  113.                 data_size = hdr2[3] + 256*hdr2[4];
  114.                 sample_rate = 1000000 / (256 - hdr2[5]);
  115.                 
  116.                 sleepTime = (data_size * 256 / sample_rate) | 0x80000000;
  117.  
  118.                 /* we want to sleep till we get our signal back */
  119.                 if (sig_pending)
  120.                 {
  121.                     while (! sigarrived)
  122.                         tsleep(0);
  123.                     sig_pending = 0;
  124.                 }
  125.                 /* now sleep for the silence time */
  126.                 tsleep(sleepTime);
  127.                 break;
  128.  
  129.             case Marker:
  130.                 size = 5;
  131.                 if ((read(fd, hdr2, size)) == -1) {
  132.                     cleanup(errno, "cannot read header2");
  133.                 }
  134.                 res = hdr2[3] + 256*hdr2[4];
  135.                 break;
  136.  
  137.             case ASCII:
  138.                 size = 2;
  139.                 if ((read(fd, hdr2, size)) == -1) {
  140.                     cleanup(errno, "cannot read header2");
  141.                 }
  142.                 res = hdr2[0] + 256*hdr2[1];
  143.                 size = res;
  144.                 if ((read(fd, comment, size)) == -1) {
  145.                     cleanup(errno, "cannot read text");
  146.                 }
  147.                 fprintf(stderr, "%s\n", comment);
  148.                 break;
  149.  
  150.             case Repeat:
  151.                 size = 5;
  152.                 if ((read(fd, hdr2, size)) == -1) {
  153.                     cleanup(errno, "cannot read header2");
  154.                 }
  155.                 repeat = hdr2[3] + 256*hdr2[4];
  156.                 loop_pos = _gs_pos(fd);
  157.                 break;
  158.  
  159.             case End_repeat:
  160.                 if (repeat > 1)
  161.                 {
  162.                     if (lseek(fd,loop_pos,SEEK_SET) == -1)
  163.                         cleanup(errno, "cannot seek back to loop point");
  164.                     repeat--;
  165.                 }
  166.                 else
  167.                     repeat = 0;
  168.                 sample_rate = 0;
  169.                 break;
  170.  
  171.             case Extended:
  172.                 size = 7;
  173.                 if ((read(fd, hdr2, size)) == -1) {
  174.                     cleanup(errno, "cannot read header2");
  175.                 }
  176.                 channels = hdr2[6] + 1;
  177.                 res = hdr2[3] + 256*hdr2[4];
  178.                 sample_rate = (256000000 / (65536 - res)) / channels;
  179.                 comp_type = hdr2[5];
  180.                 if (!quiet) {
  181.                     fprintf(stderr, "Time Constant: %-8d ",res);
  182.                     fprintf(stderr, "Sample Rate: %-8d ",sample_rate);
  183.                     fprintf(stderr, "Channels: %-2d ", channels);
  184.                     fprintf(stderr, "Compression type: %-2d\n", comp_type);
  185.                 }
  186.                 got_extended = TRUE;
  187.                 break;
  188.  
  189.             case Sound_continue:
  190.                 size = 3;
  191.                 if ((read(fd, hdr2, size)) == -1) {
  192.                     cleanup(errno, "cannot read header2");
  193.                 }
  194.                 data_size = swab3(&hdr2[0]);
  195.                 if (!quiet) {
  196.                     fprintf(stderr, "Sound length:  %-8d ", data_size);
  197.                     fprintf(stderr, "Sample Rate: %-8d ",sample_rate);
  198.                     fprintf(stderr, "Channels: %-2d ", channels);
  199.                     fprintf(stderr, "Compression type: %-2d\n", comp_type);
  200.                 }
  201.                 /* fall through */
  202.  
  203.             case Sound_data:
  204.                 if (type == Sound_data) {
  205.                     size = 5;
  206.                     if ((read(fd, hdr2, size)) == -1) {
  207.                         cleanup(errno, "cannot read header2");
  208.                     }
  209.                     data_size = swab3(&hdr2[0]) - 2;
  210.                     /* ignore sample_rate if set by extended block */
  211.                     if (!got_extended)
  212.                     {
  213.                         sample_rate = (1000000 / (256 - hdr2[3])) / channels;
  214.                         comp_type = hdr2[4];
  215.                     }
  216.                     if (!quiet) {
  217.                         fprintf(stderr, "Sound length:  %-8d ", data_size);
  218.                         fprintf(stderr, "Sample Rate: %-8d ",sample_rate);
  219.                         fprintf(stderr, "Channels: %-2d ", channels);
  220.                         fprintf(stderr, "Compression type: %-2d\n", comp_type);
  221.                     }
  222.                 }
  223.  
  224.                 if ( channels != 1 && channels != 2 ) {
  225.                     cleanup("cannot handle more than 2 channels");
  226.                 }
  227.  
  228.                 do {
  229.                     buf = buf == buf1 ? buf2 : buf1;
  230.  
  231.                     switch (comp_type) {
  232.                     case 3: /* 2 bit sound */
  233.                         size = data_size > bufferSize/4 ? bufferSize/4 : data_size;
  234.                         break;
  235.                     case 2: /* 2.6 bit sound */
  236.                         size = data_size > bufferSize/3 ? bufferSize/3 : data_size;
  237.                         break;
  238.                     case 1: /* 4 bit sound */
  239.                         size = data_size > bufferSize/2 ? bufferSize/2 : data_size;
  240.                         break;
  241.                     case 0: /* 8 bit sound */
  242.                     default:
  243.                         size = data_size > bufferSize ? bufferSize : data_size;
  244.                         break;
  245.                     }
  246.  
  247.                     if ((read(fd, buf, size)) == -1) {
  248.                         if (errno == E_EOF) {
  249.                             break;
  250.                         } else {
  251.                             cleanup(errno, "cannot read file");
  252.                         }
  253.                     }
  254.  
  255.                     data_size -= size;
  256.  
  257.                     switch (comp_type) {
  258.                     case 1: /* 4 bit sound */
  259.                         expand2(buf,size);
  260.                         size <<= 1;
  261.                         break;
  262.                     case 2: /* 2.6 bit sound */
  263.                         expand3(buf,size);
  264.                         size *= 3;
  265.                         break;
  266.                     case 3: /* 2 bit sound */
  267.                         expand4(buf,size);
  268.                         size <<= 2;
  269.                         break;
  270.                     }
  271.  
  272.                     if (channels == 2) {
  273.                         process(buf, size);
  274.                     } else {
  275.                         process1(buf, size);
  276.                     }
  277.  
  278.                     /* wait till last play is done */
  279.                     while ( sigarrived == 0) {
  280.                         sleepTime = 0;
  281.                         tsleep(sleepTime);
  282.                         sig_pending = 0;
  283.                     }
  284.                     sigarrived = 0;
  285.  
  286.                     _ss_play(1, buf, channels == 1 ? size*2 : size,
  287.                         sample_rate, SND_SENDSIG, SIG_CODE);
  288.                 } while (data_size > 0);
  289.                 /* set flag so we don't sleep till we get the signal back */
  290.                 sig_pending = 1;
  291.                 break;
  292.  
  293. #if 0
  294.             default:
  295.                 fprintf(stderr, "Unknown data block type: %d\n", type);
  296. #endif
  297.         }
  298.     }
  299. }
  300.  
  301. process(buf, n)
  302. unsigned char *buf;
  303. int n;
  304. {
  305.     int i;
  306.  
  307.     for (i = 0; i < n; i++) {
  308.         buf[i] -= 0x80;
  309.     }
  310. }
  311.  
  312. process1(buf, n)
  313. unsigned char *buf;
  314. int n;
  315. {
  316.     int i;
  317.  
  318.     for (i = n - 1; i >= 0 ; i--) {
  319.         buf[2*i + 1] = buf[2*i] = buf[i] - 0x80;
  320.     }
  321. }
  322.  
  323. /* 4-bit compression - expand 4,4 bits into 2 samples */
  324. static expand2(buf, n)
  325. unsigned char *buf;
  326. int n;
  327. {
  328.     int i;
  329.  
  330.     for (i = n-1; i >= 0; i--) {
  331.         buf[2*i] = buf[i] & 0xf0;
  332.         buf[2*i + 1] = (buf[i] << 4) & 0xf0;
  333.     }
  334. }
  335.  
  336. /* 2.6-bit compression - expand 3,3,2 bits into 3 samples */
  337. static expand3(buf, n)
  338. unsigned char *buf;
  339. int n;
  340. {
  341.     int i;
  342.  
  343.     for (i = n-1; i >= 0; i--) {
  344.         buf[3*i] = buf[i] & 0xe0;
  345.         buf[3*i + 1] = (buf[i] << 3) & 0xe0;
  346.         buf[3*i + 2] = (buf[i] << 6) & 0xc0;
  347.     }
  348. }
  349.  
  350. /* 2-bit compression - expand 2,2,2,2 bits into 4 samples */
  351. static expand4(buf, n)
  352. unsigned char *buf;
  353. int n;
  354. {
  355.     int i;
  356.  
  357.     for (i = n-1; i >= 0; i--) {
  358.         buf[4*i] = buf[i] & 0xc0;
  359.         buf[4*i + 1] = (buf[i] << 2) & 0xc0;
  360.         buf[4*i + 2] = (buf[i] << 4) & 0xc0;
  361.         buf[4*i + 3] = (buf[i] << 6) & 0xc0;
  362.     }
  363. }
  364.  
  365. int swab3(x)
  366. register unsigned char *x;
  367. {
  368.     return x[0] | (x[1] << 8) | (x[2] << 16);
  369. }
  370.  
  371. static int swab(x)
  372. register unsigned char *x;
  373. {
  374.     return x[0] | (x[1] << 8);
  375. }
  376.