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 / iffplay.c < prev    next >
Text File  |  1995-03-25  |  6KB  |  263 lines

  1. /* iffplay.c - play IFF/8SVX Amiga file on MM/1 - Andrzej Kotanski 1994 */
  2.  
  3. #include "play.h"
  4.  
  5. static struct header1 {
  6.     char magic1[4];
  7.     u_int32 totlength;
  8.     char magic2[4];
  9.     char magic3[4];
  10.     u_int32 header_length;
  11. } hdr1;
  12.  
  13. static struct header {
  14.     u_int32 one_shot_length;
  15.     u_int32 repeat_length;
  16.     u_int32 high_oct;
  17.     unsigned short sample_rate;
  18.     unsigned char octaves;
  19.     unsigned char compress;
  20.     u_int32 volume;
  21. } hdr;
  22.  
  23. static struct header2 {
  24.     char name[4];
  25.     u_int32 size;
  26. } hdr2;
  27.  
  28. static int data_size;
  29. static char *buf1, *buf2, *buf;
  30. static int channels = 1;
  31. static char title[1000];
  32. char *malloc();
  33.  
  34.  
  35. iffplay(fd,fname)
  36. path_id fd;
  37. char *fname;
  38. {
  39.     u_int32 res, sleepTime;
  40.     u_int32 chan, i;
  41.     u_int32 _gs_pos(), lseek(), offset;
  42.     u_int32 position;
  43.     path_id fd2;
  44.     char *Lchan, *Rchan, *Stereobuf;
  45.  
  46.     size = sizeof(hdr1);
  47.     if ((read(fd, &hdr1, size)) == -1) {
  48.         cleanup(errno, "cannot read header");
  49.     }
  50.  
  51.     if ( strncmp(hdr1.magic1, "FORM", 4)
  52.         || strncmp(hdr1.magic2, "8SVX", 4)
  53.         || strncmp(hdr1.magic3, "VHDR", 4)  ) {
  54.         cleanup(0, "bad magic number");
  55.     }
  56.  
  57.     if ( hdr1.header_length != 0x14 ) {
  58.         cleanup(0, "non-standard header length");
  59.     }
  60.  
  61.     size = sizeof(hdr);
  62.     if ((read(fd, &hdr, size)) == -1) {
  63.         cleanup(errno, "cannot read header");
  64.     }
  65.  
  66.     do {
  67.         size = sizeof(hdr2);
  68.         if ((read(fd, &hdr2, size)) == -1) {
  69.             cleanup(errno, "cannot read chunk header");
  70.         }
  71.  
  72.         if ( strncmp(hdr2.name, "NAME", 4) == 0 ) {
  73.             size = hdr2.size;
  74.             if ((read(fd, title, size)) == -1) {
  75.                 cleanup(errno, "cannot read NAME");
  76.             }
  77.  
  78.             if (!quiet) {
  79.                 fprintf(stderr, "Name: %s\n", title);
  80.             }
  81.         } else if ( strncmp(hdr2.name, "ANNO", 4) == 0 ) {
  82.             size = hdr2.size;
  83.             if ((read(fd, title, size)) == -1) {
  84.                 cleanup(errno, "cannot read ANNO");
  85.             }
  86.             if (!quiet) {
  87.                 fprintf(stderr, "ANNO: %s\n", title);
  88.             }
  89.         } else if ( strncmp(hdr2.name, "CHAN", 4) == 0 ) {
  90.             size = 4;
  91.             if ((read(fd, &chan, size)) == -1) {
  92.                 cleanup(errno, "cannot read CHAN");
  93.             }
  94.             channels = 0;
  95.             for (i = 1; i < 31; i++) {
  96.                 if (chan & (1 << i))
  97.                     channels++;
  98.             }
  99.             if (channels == 0)
  100.                 channels = 1;
  101.         } else if ( strncmp(hdr2.name, "BODY", 4) ) {
  102.             if (!quiet) {
  103.                 fprintf(stderr, "Unknown chunk: %s, trying to skip...\n", hdr2.name);
  104.             }
  105.             position = _gs_pos(fd);
  106.             if ((lseek(fd, position + hdr2.size,SEEK_SET)) == -1) {
  107.                 cleanup(errno, "cannot seek...");
  108.             }
  109.         }
  110.     } while ( strncmp(hdr2.name, "BODY", 4) );
  111.  
  112.     data_size = hdr2.size;
  113.  
  114.     if (!quiet) {
  115.         fprintf(stderr, "Length: %d\n", data_size);
  116.         fprintf(stderr, "Sample rate: %d\n", hdr.sample_rate);
  117.         fprintf(stderr, "Channels: %d\n", channels);
  118.     }
  119.  
  120.     if (channels == 1) {
  121.         buf1 = malloc(bufferSize*2);
  122.         buf2 = malloc(bufferSize*2);
  123.     } else {
  124.         /* open a path for our second channel */
  125.         if ((fd2 = open(fname, S_IREAD)) == -1) {
  126.             cleanup(errno, "cannot open second channel...");
  127.         }
  128.  
  129.         /* calc offset to second channel's data */
  130.         offset = data_size / channels;
  131.  
  132.         /* reassign data_size to the channel size */
  133.         data_size = offset;
  134.  
  135.         if ((position = _gs_pos(fd)) == -1) {
  136.             cleanup(errno, "cannot get current file position...");
  137.         }
  138.         /* seek to 2nd channel */
  139.         if ((lseek(fd, offset ,SEEK_CUR)) == -1) {
  140.             cleanup(errno, "cannot seek into second channel...");
  141.         }
  142. #if 0
  143.         printf("Second channel is at %d\n",_gs_pos(fd));
  144. #endif
  145.         /* seek to 1st channel */
  146.         if ((lseek(fd2, position,SEEK_SET)) == -1) {
  147.             cleanup(errno, "cannot seek to first channel...");
  148.         }
  149. #if 0
  150.         printf("First channel is at %d\n",_gs_pos(fd2));
  151. #endif
  152.         /* get play buffers */
  153.         buf1 = malloc(bufferSize);
  154.         buf2 = malloc(bufferSize);
  155.  
  156.         /* allocate our buffer */
  157.         Stereobuf = malloc(bufferSize);
  158.         if (Stereobuf == NULL) {
  159.             cleanup(errno, "cannot allocate stereo buffer");
  160.         }
  161.  
  162.         /* assign our pointers into the buffer */
  163.         Lchan = Stereobuf;
  164.         Rchan = Stereobuf + (bufferSize / 2);
  165.     }
  166.  
  167.     if (buf1 == NULL || buf2 == NULL) {
  168.         cleanup(errno, "cannot allocate buffer");
  169.     }
  170.  
  171.     buf = buf2;
  172.     sigarrived = 1;
  173.  
  174.     do {
  175.         buf = buf == buf1 ? buf2 : buf1;
  176.         if ( channels == 1 ) {
  177.             /* only read remaining or bufferSize bytes */
  178.             res = (data_size > bufferSize) ? bufferSize : data_size;
  179.             if ((read(fd, buf, res)) == -1) {
  180.                 if (errno == E_EOF) {
  181.                     break;
  182.                 } else {
  183.                     cleanup(errno, "cannot read file");
  184.                 }
  185.             }
  186.             data_size -= res;
  187.             process1(buf, res);
  188.         } else {
  189.             /* only read remaining or bufferSize / 2 bytes */            
  190.             res = (data_size > bufferSize/2) ? bufferSize/2 : data_size;
  191.             if ((read(fd, Rchan, res)) != res) {
  192.                 cleanup(errno, "cannot read right channel");
  193.             }
  194.             if ((read(fd2, Lchan, res)) != res) {
  195.                 cleanup(errno, "cannot read left channel");
  196.             }
  197.             data_size -= res;
  198. #if 0
  199.             printf("This read (%d)\n",res);
  200. #endif
  201.             combine(Lchan,Rchan,buf,res);
  202.         }
  203.  
  204.         if ( sigarrived == 0) {
  205.             sleepTime = 0;
  206.             tsleep(sleepTime);
  207.         }
  208.  
  209.         sigarrived = 0;
  210. #if 0
  211.         printf("Len (%d), Srate (%d)\n",res * 2, hdr.sample_rate);
  212. #endif            
  213.         _ss_play(1, buf, res*2, hdr.sample_rate, SND_SENDSIG, SIG_CODE);
  214.  
  215.     } while ( data_size > 0 );
  216.  
  217.     /* clean up if stereo */
  218.     if (channels > 1)
  219.     {
  220.         close(fd2);
  221.         free(Stereobuf);
  222.     }
  223.     
  224.     sleepTime = 0;
  225.     tsleep(sleepTime);
  226.  
  227.     /* free up memory */
  228.     free(buf1);
  229.     free(buf2);
  230.     close(fd);
  231. }
  232.  
  233.  
  234. static int process1(buf, n)
  235. unsigned char *buf;
  236. int n;
  237. {
  238.     int32 i;
  239.  
  240.     for (i = n - 1; i >= 0 ; i--) {
  241.         buf[2*i + 1] = buf[2*i] = buf[i];
  242.     }
  243. }
  244.  
  245. static int combine(left,right,buf, n)
  246. unsigned char *left,*right,*buf;
  247. int n;
  248. {
  249.     int32 i,j;
  250.  
  251. #if 0
  252.     printf("Combining %d bytes\n",n);
  253. #endif    
  254.     for (j = 0,i = 0; i < n; i++,j += 2) {
  255.         buf[j]   = right[i];
  256.         buf[j+1] = left[i];
  257.     }
  258. #if 0
  259.     printf("Done i(%d),j(%d),n(%d)\n",i,j,n);
  260. #endif
  261. }
  262.  
  263.