home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 3 / AACD03.BIN / AACD / Sound / SoX / Source / sf.c < prev    next >
C/C++ Source or Header  |  1999-07-18  |  6KB  |  223 lines

  1. /*
  2.  * July 5, 1991
  3.  * Copyright 1991 Lance Norskog And Sundry Contributors
  4.  * This source code is freely redistributable and may be used for
  5.  * any purpose.  This copyright notice must be maintained. 
  6.  * Lance Norskog And Sundry Contributors are not responsible for 
  7.  * the consequences of using this software.
  8.  */
  9.  
  10. /*
  11.  * Sound Tools IRCAM SoundFile format handler.
  12.  * 
  13.  * Derived from: Sound Tools skeleton handler file.
  14.  */
  15.  
  16. #define    IRCAM
  17. #include "st.h"
  18. #ifdef    IRCAM
  19. #include "sfircam.h"
  20. #ifndef SIZEOF_BSD_HEADER
  21. #define SIZEOF_BSD_HEADER 1024
  22. #endif
  23. #else
  24. #include "sfheader.h"
  25. #endif
  26. #include <string.h>
  27. #include <stdlib.h>
  28. #ifdef HAVE_MALLOC_H
  29. #include <malloc.h>
  30. #endif
  31.  
  32. /* Private data for SF file */
  33. typedef struct sfstuff {
  34.     struct sfinfo info;
  35. } *sf_t;
  36.  
  37. /*
  38.  * Read the codes from the sound file, allocate space for the comment and
  39.  * assign its pointer to the comment field in ft.
  40.  */
  41. void readcodes(ft, sfhead)
  42. ft_t ft;
  43. SFHEADER *sfhead;
  44. {
  45.     char *commentbuf = NULL, *sfcharp, *newline;
  46.     short bsize, finished = 0;
  47.     SFCODE *sfcodep;
  48.  
  49.     sfcodep = (SFCODE *) &sfcodes(sfhead);
  50.     do {
  51.         sfcharp = (char *) sfcodep + sizeof(SFCODE);
  52.         if (ft->swap) {
  53.             sfcodep->bsize = swapl(sfcodep->bsize);
  54.             sfcodep->code = swapl(sfcodep->code);
  55.         }
  56.         bsize = sfcodep->bsize - sizeof(SFCODE);
  57.         switch(sfcodep->code) {
  58.         case SF_END:
  59.             finished = 1;
  60.             break;
  61.         case SF_COMMENT:
  62.             if((commentbuf = (char *) malloc(bsize + 1)) != NULL) {
  63.                 memcpy(commentbuf, sfcharp, bsize);
  64.                 report("IRCAM comment: %s", sfcharp);
  65.                 commentbuf[bsize] = '\0';
  66.                 if((newline = strchr(commentbuf, '\n')) != NULL)
  67.                     *newline = '\0';
  68.             }
  69.             break;
  70.         }
  71.         sfcodep = (SFCODE *) (sfcharp + bsize);
  72.     } while(!finished);
  73.     if(commentbuf != NULL)    /* handles out of memory condition as well */
  74.         ft->comment = commentbuf;
  75. }
  76.  
  77. /*
  78.  * Do anything required before you start reading samples.
  79.  * Read file header. 
  80.  *    Find out sampling rate, 
  81.  *    size and style of samples, 
  82.  *    mono/stereo/quad.
  83.  */
  84. void sfstartread(ft) 
  85. ft_t ft;
  86. {
  87.     sf_t sf = (sf_t) ft->priv;
  88.     SFHEADER sfhead;
  89.  
  90.     /* Needed for rawread() */
  91.     rawstartread(ft);
  92.     
  93.     if (fread(&sfhead, 1, sizeof(SFHEADER), ft->fp) != sizeof(SFHEADER))
  94.         fail("unexpected EOF in SF header");
  95.     memcpy(&sf->info, &sfhead.sfinfo, sizeof(struct sfinfo));
  96.     if (ft->swap) {
  97. #ifdef    IRCAM
  98.         sf->info.sf_srate = swapf(sf->info.sf_srate);
  99. #else
  100.         sf->info.sf_magic = swapl(sf->info.sf_magic);
  101.         sf->info.sf_srate = swapl(sf->info.sf_srate);
  102. #endif
  103.         sf->info.sf_packmode = swapl(sf->info.sf_packmode);
  104.         sf->info.sf_chans = swapl(sf->info.sf_chans);
  105.     }
  106. #ifdef    IRCAM
  107.     if ((sfmagic1(&sfhead) != SF_MAGIC1) ||
  108.         (sfmagic2(&sfhead) != SF_MAGIC2))
  109.         fail(
  110. "SF %s file: can't read, it is byte-swapped or it is not an IRCAM SoundFile", 
  111.             ft->filename);
  112. #else
  113.     if (sf->info.sf_magic != SF_MAGIC)
  114.         if (sf->info.sf_magic == swapl(SF_MAGIC))
  115. fail("SF %s file: can't read, it is probably byte-swapped");
  116.             else
  117. fail("SF %s file: can't read, it is not an IRCAM SoundFile");
  118. #endif
  119.  
  120.  
  121.     /*
  122.      * If your format specifies or your file header contains
  123.      * any of the following information. 
  124.      */
  125.     ft->info.rate = sf->info.sf_srate;
  126.     switch(sf->info.sf_packmode) {
  127.         case SF_SHORT:
  128.             ft->info.size = WORD;
  129.             ft->info.style = SIGN2;
  130.             break;
  131.         case SF_FLOAT:
  132.             ft->info.size = FLOAT;
  133.             ft->info.style = SIGN2;
  134.             break;
  135.         default:
  136.             fail("Soundfile input: unknown format 0x%x\n",
  137.                 sf->info.sf_packmode);
  138.     }
  139.     ft->info.channels = (int) sf->info.sf_chans;
  140.  
  141.     /* Read codes and print as comments. */
  142.     readcodes(ft, &sfhead);
  143. }
  144.  
  145. void sfstartwrite(ft) 
  146. ft_t ft;
  147. {
  148.     sf_t sf = (sf_t) ft->priv;
  149.     SFHEADER sfhead;
  150.     SFCODE *sfcodep;
  151.     char *sfcharp;
  152.     int littlendian = 1;
  153.     char *endptr;
  154.  
  155.     /* Needed for rawwrite() */
  156.     rawstartwrite(ft);
  157.  
  158. #ifdef    IRCAM
  159.     sf->info.magic_union._magic_bytes.sf_magic1 = SF_MAGIC1;
  160.     sf->info.magic_union._magic_bytes.sf_magic2 = SF_MAGIC2;
  161.     sf->info.magic_union._magic_bytes.sf_param = 0;
  162.     /* computer musicians can't code worth a damn */
  163.     /* you don't see this kind of junk in any other format */
  164.     endptr = (char *) &littlendian;
  165.     *endptr = 1;
  166.     if (littlendian == 1)
  167.         sf->info.magic_union._magic_bytes.sf_machine = SF_VAX;
  168.     else
  169.         sf->info.magic_union._magic_bytes.sf_machine = SF_SUN;
  170. #else
  171.     sf->info.sf_magic = SF_MAGIC;
  172. #endif
  173.     sf->info.sf_srate = ft->info.rate;
  174. #ifdef    LATER
  175.     /* 
  176.      * CSound sound-files have many formats. 
  177.      * We stick with the IRCAM short-or-float scheme.
  178.      */
  179.     if (ft->info.size == WORD) {
  180.         sf->info.sf_packmode = SF_SHORT;
  181.         ft->info.style = SIGN2;        /* Default to signed words */
  182.     } else if (ft->info.size == FLOAT)
  183.         sf->info.sf_packmode = SF_FLOAT;
  184.     else
  185.         fail("SoundFile %s: must set output as signed shorts or floats",
  186.             ft->filename);
  187. #else
  188.     if (ft->info.size == FLOAT) {
  189.         sf->info.sf_packmode = SF_FLOAT;
  190.         ft->info.size = FLOAT;
  191.     } else {
  192.         sf->info.sf_packmode = SF_SHORT;
  193.         ft->info.size = WORD;
  194.         ft->info.style = SIGN2;        /* Default to signed words */
  195.     }
  196. #endif
  197.     sf->info.sf_chans = ft->info.channels;
  198.  
  199.     /* Clean out structure so unused areas will remain constain  */
  200.     /* between different coverts and not rely on memory contents */
  201.     memset (&sfhead, 0, sizeof(SFHEADER));
  202.     memcpy(&sfhead.sfinfo, &sf->info, sizeof(struct sfinfo));
  203.     sfcodep = (SFCODE *) &sfcodes(&sfhead);
  204.     sfcodep->code = SF_COMMENT;
  205.     sfcodep->bsize = strlen(ft->comment) + sizeof(SFCODE);
  206.     while (sfcodep->bsize % 4)
  207.         sfcodep->bsize++;
  208.     sfcharp = (char *) sfcodep;
  209.     strcpy(sfcharp + sizeof(SFCODE), ft->comment);
  210.     sfcodep = (SFCODE *) (sfcharp + sfcodep->bsize);
  211.     sfcodep->code = SF_END;
  212.     sfcodep->bsize = sizeof(SFCODE);
  213.     sfcharp = (char *) sfcodep + sizeof(SFCODE);
  214.     while(sfcharp < (char *) &sfhead + SIZEOF_BSD_HEADER)
  215.         *sfcharp++ = '\0';
  216.     (void) fwrite(&sfhead, 1, sizeof(SFHEADER), ft->fp);
  217. }
  218.  
  219. /* Read and write are supplied by raw.c */
  220.  
  221.  
  222.  
  223.