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

  1. /*
  2.  * Sounder/Sndtool format handler: W V Neisius, February 1992
  3.  *
  4.  * June 28, 93: force output to mono.
  5.  * 
  6.  * March 3, 1999 - cbagwell@sprynet.com
  7.  *   Forced extra comment fields to zero.
  8.  */
  9.  
  10. #include <math.h>
  11. #include <string.h>
  12. #include <stdio.h>
  13.  
  14. #ifdef HAVE_UNISTD_H
  15. #include <unistd.h>    /* For SEEK_* defines if not found in stdio */
  16. #endif
  17.  
  18. #include "st.h"
  19.  
  20. /* Private data used by writer */
  21. struct sndpriv {
  22.         ULONG nsamples;
  23. };
  24.  
  25. #ifndef    SEEK_CUR
  26. #define    SEEK_CUR    1
  27. #endif
  28.  
  29. void  sndtwriteheader(P2(ft_t ft,LONG nsamples));
  30. void rawwrite(P3(ft_t, LONG *, LONG));
  31.  
  32. /*======================================================================*/
  33. /*                         SNDSTARTREAD                                */
  34. /*======================================================================*/
  35.  
  36. void sndtstartread(ft)
  37. ft_t ft;
  38. {
  39. char buf[97];
  40.  
  41. LONG rate;
  42.  
  43.     int littlendian = 1;
  44.     char *endptr;
  45.  
  46.     /* Needed for rawread() */
  47.     rawstartread(ft);
  48.  
  49.     endptr = (char *) &littlendian;
  50.     /* sndt is in little endian format so 
  51.      * swap bytes on big endian machines.
  52.      */
  53.     if (!*endptr)
  54.     {
  55.         ft->swap = ft->swap ? 0 : 1;
  56.     }
  57.  
  58.     rate = 0;
  59.  
  60. /* determine file type */
  61.         /* if first 5 bytes == SOUND then this is probably a sndtool sound */
  62.         /* if first word (16 bits) == 0 
  63.          and second word is between 4000 & 25000 then this is sounder sound */
  64.         /* otherwise, its probably raw, not handled here */
  65.  
  66. if (fread(buf, 1, 2, ft->fp) != 2)
  67.     fail("SND: unexpected EOF");
  68. if (strncmp(buf,"\0\0",2) == 0)
  69.     {
  70.     /* sounder */
  71.     rate = rshort(ft);
  72.     if (rate < 4000 || rate > 25000 )
  73.         fail ("SND: sample rate out of range");
  74.     fseek(ft->fp,4,SEEK_CUR);
  75.     }
  76. else
  77.     {
  78.     /* sndtool ? */
  79.     fread(&buf[2],1,6,ft->fp);
  80.     if (strncmp(buf,"SOUND",5))
  81.         fail ("SND: unrecognized SND format");
  82.     fseek(ft->fp,12,SEEK_CUR);
  83.     rate = rshort(ft);
  84.     fseek(ft->fp,6,SEEK_CUR);
  85.     if (fread(buf,1,96,ft->fp) != 96)
  86.         fail ("SND: unexpected EOF in SND header");
  87.     report ("%s",buf);
  88.     }
  89.  
  90. ft->info.channels = 1;
  91. ft->info.rate = rate;
  92. ft->info.style = UNSIGNED;
  93. ft->info.size = BYTE;
  94.  
  95. }
  96.  
  97. /*======================================================================*/
  98. /*                         SNDTSTARTWRITE                               */
  99. /*======================================================================*/
  100. void sndtstartwrite(ft)
  101. ft_t ft;
  102. {
  103. struct sndpriv *p = (struct sndpriv *) ft->priv;
  104.  
  105.     int littlendian = 1;
  106.     char *endptr;
  107.  
  108.     /* Needed for rawwrite() */
  109.     rawstartwrite(ft);
  110.  
  111.     endptr = (char *) &littlendian;
  112.     /* sndt is in little endian format so
  113.      * swap bytes on big endian machines
  114.      */
  115.     if (!*endptr)
  116.     {
  117.         ft->swap = ft->swap ? 0 : 1;
  118.     }
  119.  
  120. /* write header */
  121. ft->info.channels = 1;
  122. ft->info.style = UNSIGNED;
  123. ft->info.size = BYTE;
  124. p->nsamples = 0;
  125. sndtwriteheader(ft, 0);
  126.  
  127. }
  128. /*======================================================================*/
  129. /*                         SNDRSTARTWRITE                               */
  130. /*======================================================================*/
  131. void sndrstartwrite(ft)
  132. ft_t ft;
  133. {
  134.     int littlendian = 1;
  135.     char *endptr;
  136.  
  137.     /* Needed for rawread() */
  138.     rawstartread(ft);
  139.  
  140.     endptr = (char *) &littlendian;
  141.     /* sndr is in little endian format so
  142.      * swap bytes on big endian machines
  143.      */
  144.     if (!*endptr)
  145.     {
  146.         ft->swap = ft->swap ? 0 : 1;
  147.     }
  148.  
  149. /* write header */
  150. ft->info.channels = 1;
  151. ft->info.style = UNSIGNED;
  152. ft->info.size = BYTE;
  153.  
  154. /* sounder header */
  155. wshort (ft,0); /* sample size code */
  156. wshort (ft,(int) ft->info.rate);     /* sample rate */
  157. wshort (ft,10);        /* volume */
  158. wshort (ft,4); /* shift */
  159. }
  160.  
  161. /*======================================================================*/
  162. /*                         SNDTWRITE                                     */
  163. /*======================================================================*/
  164.  
  165. void sndtwrite(ft, buf, len)
  166. ft_t ft;
  167. LONG *buf, len;
  168. {
  169.     struct sndpriv *p = (struct sndpriv *) ft->priv;
  170.     p->nsamples += len;
  171.     rawwrite(ft, buf, len);
  172. }
  173.  
  174. /*======================================================================*/
  175. /*                         SNDTSTOPWRITE                                */
  176. /*======================================================================*/
  177.  
  178. void sndtstopwrite(ft)
  179. ft_t ft;
  180. {
  181.     struct sndpriv *p = (struct sndpriv *) ft->priv;
  182.  
  183.     /* Flush remaining buffer out */
  184.     rawstopwrite(ft);
  185.  
  186.     /* fixup file sizes in header */
  187.     if (fseek(ft->fp, 0L, 0) != 0)
  188.         fail("can't rewind output file to rewrite SND header");
  189.     sndtwriteheader(ft, p->nsamples);
  190. }
  191.  
  192. /*======================================================================*/
  193. /*                         SNDTWRITEHEADER                              */
  194. /*======================================================================*/
  195. void sndtwriteheader(ft,nsamples)
  196. ft_t ft;
  197. LONG nsamples;
  198. {
  199. char name_buf[97];
  200.  
  201. /* sndtool header */
  202. fputs ("SOUND",ft->fp); /* magic */
  203. fputc (0x1a,ft->fp);
  204. wshort (ft,(LONG)0);  /* hGSound */
  205. wlong (ft,nsamples);
  206. wlong (ft,(LONG)0);
  207. wlong (ft,nsamples);
  208. wshort (ft,(int) ft->info.rate);
  209. wshort (ft,0);
  210. wshort (ft,10);
  211. wshort (ft,4);
  212. memset (name_buf, 0, 96);
  213. sprintf (name_buf,"%s - File created by Sound Exchange",ft->filename);
  214. fwrite (name_buf, 1, 96, ft->fp);
  215. }
  216.  
  217.  
  218.