home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 3 / AACD03.BIN / AACD / Sound / SoX / Source / raw.c < prev    next >
C/C++ Source or Header  |  1999-07-18  |  10KB  |  522 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 raw format file.
  12.  *
  13.  * Includes .ub, .uw, .sb, .sw, and .ul formats at end
  14.  */
  15.  
  16. /*
  17.  * Notes: most of the headerless formats set their handlers to raw
  18.  * in their startread/write routines.  
  19.  *
  20.  */
  21.  
  22. #include "st.h"
  23. #include "libst.h"
  24.  
  25. #ifdef HAVE_MALLOC_H
  26. #include <malloc.h>
  27. #endif
  28.  
  29. #include <stdlib.h>
  30.  
  31. void rawstartread(ft) 
  32. ft_t ft;
  33. {
  34.     ft->file.buf = malloc(BUFSIZ);
  35.     ft->file.size = BUFSIZ;
  36.     ft->file.count = 0;
  37.     ft->file.pos = 0;
  38.     ft->file.eof = 0;
  39. }
  40.  
  41. void rawstartwrite(ft) 
  42. ft_t ft;
  43. {
  44.     ft->file.buf = malloc(BUFSIZ);
  45.     ft->file.size = BUFSIZ;
  46.     ft->file.pos = 0;
  47.     ft->file.eof = 0;
  48. }
  49.  
  50. /* Read raw file data, and convert it to */
  51. /* the sox internal signed long format. */
  52.  
  53. unsigned char blockgetc(ft)
  54. ft_t ft;
  55. {
  56.     char rval;
  57.  
  58.     if (ft->file.pos == ft->file.count)
  59.     {
  60.         if (ft->file.eof)
  61.             return(0);
  62.         ft->file.count = fread(ft->file.buf, 1, ft->file.size,
  63.                 ft->fp);
  64.         ft->file.pos = 0;
  65.         if (ft->file.count == 0)
  66.         {
  67.             ft->file.eof = 1;
  68.             return(0);
  69.         }
  70.     }
  71.     rval = *(ft->file.buf + ft->file.pos++);
  72.     return (rval);
  73. }
  74.  
  75. unsigned short blockrshort(ft)
  76. ft_t ft;
  77. {
  78.     unsigned short rval;
  79.     if (ft->file.pos > ft->file.count-2)
  80.     {
  81.         if (ft->file.eof)
  82.             return(0);
  83.  
  84.         if (ft->file.pos == ft->file.count-1)
  85.         {
  86.             *ft->file.buf = *(ft->file.buf + ft->file.pos);
  87.             ft->file.count = fread(ft->file.buf + 1,
  88.                     1, ft->file.size-1,
  89.                     ft->fp);
  90.         }
  91.         else
  92.         {
  93.             ft->file.count = fread(ft->file.buf, 1, ft->file.size,
  94.                     ft->fp);
  95.         }
  96.         ft->file.pos = 0;
  97.         if (ft->file.count < 2)
  98.         {
  99.             ft->file.eof = 1;
  100.             return(0);
  101.         }
  102.     }
  103.     rval = *((unsigned short *)(ft->file.buf + ft->file.pos));
  104.     ft->file.pos += 2;
  105.     if (ft->swap)
  106.         rval = swapw(rval);
  107.     return(rval);
  108. }
  109.  
  110. float blockrfloat(ft)
  111. ft_t ft;
  112. {
  113.     float rval;
  114.  
  115.     if (ft->file.count < sizeof(float))
  116.     {
  117.         ft->file.count = fread(ft->file.buf, 1, ft->file.size,
  118.                 ft->fp);
  119.         if (ft->file.count == 0)
  120.         {
  121.             ft->file.eof = 1;
  122.             return(0);
  123.         }
  124.     }
  125.     rval = *((float *)(ft->file.buf + (ft->file.size - ft->file.count)));
  126.     ft->file.count -= sizeof(float);
  127.     if (ft->swap)
  128.         rval = swapf(rval);
  129.     return(rval);
  130. }
  131.     
  132.  
  133. LONG rawread(ft, buf, nsamp) 
  134. ft_t ft;
  135. LONG *buf, nsamp;
  136. {
  137.     register LONG datum;
  138.     int done = 0;
  139.  
  140.     switch(ft->info.size) {
  141.         case BYTE:
  142.             switch(ft->info.style)
  143.             {
  144.             case SIGN2:
  145.                 while(done < nsamp) {
  146.                     datum = blockgetc(ft);
  147.                     if (ft->file.eof)
  148.                         return done;
  149.                     /* scale signed up to long's range */
  150.                     *buf++ = LEFT(datum, 24);
  151.                     done++;
  152.                 }
  153.                 return done;
  154.             case UNSIGNED:
  155.                 while(done < nsamp) {
  156.                     datum = blockgetc(ft);
  157.                     if (ft->file.eof)
  158.                         return done;
  159.                     /* Convert to signed */
  160.                     datum ^= 128;
  161.                     /* scale signed up to long's range */
  162.                     *buf++ = LEFT(datum, 24);
  163.                     done++;
  164.                 }
  165.                 return done;
  166.             case ULAW:
  167.                 while(done < nsamp) {
  168.                     datum = blockgetc(ft);
  169.                     if (ft->file.eof)
  170.                         return done;
  171.                     datum = st_ulaw_to_linear(datum);
  172.                     /* scale signed up to long's range */
  173.                     *buf++ = LEFT(datum, 16);
  174.                     done++;
  175.                 }
  176.                 return done;
  177.             case ALAW:
  178.                 while(done < nsamp) {
  179.                         datum = blockgetc(ft);
  180.                         if (ft->file.eof)
  181.                                 return done;
  182.                         datum = st_Alaw_to_linear(datum);
  183.                         /* scale signed up to long's range */
  184.                         *buf++ = LEFT(datum, 16);
  185.                         done++;
  186.                 }
  187.  
  188.                 return done;
  189.             }
  190.             break;
  191.         case WORD:
  192.             switch(ft->info.style)
  193.             {
  194.             case SIGN2:
  195.                 while(done < nsamp) {
  196.                     datum = blockrshort(ft);
  197.                     if (ft->file.eof)
  198.                         return done;
  199.                     /* scale signed up to long's range */
  200.                     *buf++ = LEFT(datum, 16);
  201.                     done++;
  202.                 }
  203.                 return done;
  204.             case UNSIGNED:
  205.                 while(done < nsamp) {
  206.                     datum = blockrshort(ft);
  207.                     if (ft->file.eof)
  208.                         return done;
  209.                     /* Convert to signed */
  210.                     datum ^= 0x8000;
  211.                     /* scale signed up to long's range */
  212.                     *buf++ = LEFT(datum, 16);
  213.                     done++;
  214.                 }
  215.                 return done;
  216.             case ULAW:
  217.                 fail("No U-Law support for shorts");
  218.                 return done;
  219.             case ALAW:
  220.                 fail("No A-Law support for shorts");
  221.                 return done;
  222.             }
  223.             break;
  224.         case FLOAT:
  225.             while(done < nsamp) {
  226.                 datum = blockrfloat(ft);
  227.                 if (ft->file.eof)
  228.                     return done;
  229.                 *buf++ = LEFT(datum, 16);
  230.                 done++;
  231.             }
  232.             return done;
  233.         default:
  234.             fail("Drop through in rawread!");
  235.     }
  236.     fail("Sorry, don't have code to read %s, %s",
  237.         styles[ft->info.style], sizes[ft->info.size]);
  238.     return(0);
  239. }
  240.  
  241. void rawstopread(ft)
  242. ft_t ft;
  243. {
  244.     free(ft->file.buf);
  245. }
  246.  
  247. void blockflush(ft)
  248. ft_t ft;
  249. {
  250.     if (fwrite(ft->file.buf, 1, ft->file.pos, ft->fp) != ft->file.pos)
  251.     {
  252.         fail("Error writing data to file");
  253.     }
  254.     ft->file.pos = 0;
  255. }
  256.  
  257. void blockputc(ft,c)
  258. ft_t ft;
  259. int c;
  260. {
  261.     if (ft->file.pos == ft->file.size) blockflush(ft);
  262.     *(ft->file.buf + ft->file.pos) = c;
  263.     ft->file.pos++;
  264. }
  265.  
  266. void blockwshort(ft,ui)
  267. ft_t ft;
  268. unsigned short ui;
  269. {
  270.     if (ft->file.pos > ft->file.size-2) blockflush(ft);
  271.     if (ft->swap)
  272.         ui = swapw(ui);
  273.     *(unsigned short *)(ft->file.buf + ft->file.pos) = ui;
  274.     ft->file.pos += 2;
  275. }
  276.  
  277. void blockwfloat(ft,f)
  278. ft_t ft;
  279. float f;
  280. {
  281.     if (ft->file.pos > ft->file.size - sizeof(float)) blockflush(ft);
  282.     if (ft->swap)
  283.         f = swapf(f);
  284.     *(float *)(ft->file.buf + ft->file.pos) = f;
  285.     ft->file.pos += sizeof(float);
  286. }
  287.  
  288. /* Convert the sox internal signed long format */
  289. /* to the raw file data, and write it. */
  290.  
  291. void
  292. rawwrite(ft, buf, nsamp) 
  293. ft_t ft;
  294. LONG *buf, nsamp;
  295. {
  296.     register int datum;
  297.     int done = 0;
  298.  
  299.     switch(ft->info.size) {
  300.         case BYTE:
  301.             switch(ft->info.style)
  302.             {
  303.             case SIGN2:
  304.                 while(done < nsamp) {
  305.                     /* scale signed up to long's range */
  306.                     datum = (int) RIGHT(*buf++, 24);
  307.                     blockputc(ft, datum);
  308.                     done++;
  309.                 }
  310.                 return;
  311.             case UNSIGNED:
  312.                 while(done < nsamp) {
  313.                     /* scale signed up to long's range */
  314.                     datum = (int) RIGHT(*buf++, 24);
  315.                     /* Convert to unsigned */
  316.                     datum ^= 128;
  317.                     blockputc(ft, datum);
  318.                     done++;
  319.                 }
  320.                 return;
  321.             case ULAW:
  322.                 while(done < nsamp) {
  323.                     /* scale signed up to long's range */
  324.                     datum = (int) RIGHT(*buf++, 16);
  325.                     /* round up to 12 bits of data */
  326.                     datum += 0x8;    /* + 0b1000 */
  327.                     datum = st_linear_to_ulaw(datum);
  328.                     blockputc(ft, datum);
  329.                     done++;
  330.                 }
  331.                 return;
  332.             case ALAW:
  333.                 while(done < nsamp) {
  334.                     /* scale signed up to long's range */
  335.                     datum = (int) RIGHT(*buf++, 16);
  336.                     /* round up to 12 bits of data */
  337.                     datum += 0x8;    /* + 0b1000 */
  338.                     datum = st_linear_to_Alaw(datum);
  339.                     blockputc(ft, datum);
  340.                     done++;
  341.                 }
  342.                 return;
  343.             }
  344.             break;
  345.         case WORD:
  346.             switch(ft->info.style)
  347.             {
  348.             case SIGN2:
  349.                 while(done < nsamp) {
  350.                     /* scale signed up to long's range */
  351.                     datum = (int) RIGHT(*buf++, 16);
  352.                     blockwshort(ft, datum);
  353.                     done++;
  354.                 }
  355.                 return;
  356.             case UNSIGNED:
  357.                 while(done < nsamp) {
  358.                     /* scale signed up to long's range */
  359.                     datum = (int) RIGHT(*buf++, 16);
  360.                     /* Convert to unsigned */
  361.                     datum ^= 0x8000;
  362.                     blockwshort(ft, datum);
  363.                     done++;
  364.                 }
  365.                 return;
  366.             case ULAW:
  367. fail("No U-Law support for shorts (try -b option ?)");
  368.                 return;
  369.             case ALAW:
  370. fail("No A-Law support for shorts (try -b option ?)");
  371.                 return;
  372.             }
  373.             break;
  374.         case FLOAT:
  375.             while(done < nsamp) {
  376.                 /* scale signed up to long's range */
  377.                 datum = (int) RIGHT(*buf++, 16);
  378.                  blockwfloat(ft, (double) datum);
  379.                 done++;
  380.             }
  381.             return;
  382.         default:
  383.             fail("Drop through in rawwrite!");
  384.     }
  385.     fail("Sorry, don't have code to write %s, %s",
  386.         styles[ft->info.style], sizes[ft->info.size]);
  387. }
  388.  
  389. void rawstopwrite(ft)
  390. ft_t ft;
  391. {
  392.     blockflush(ft);
  393.     free(ft->file.buf);
  394. }
  395.  
  396. /*
  397. * Set parameters to the fixed parameters known for this format,
  398. * and change format to raw format.
  399. */
  400.  
  401. void rawdefaults();
  402.  
  403. /* Signed byte */
  404. void sbstartread(ft) 
  405. ft_t ft;
  406. {
  407.     ft->info.size = BYTE;
  408.     ft->info.style = SIGN2;
  409.     rawstartread(ft);
  410.     rawdefaults(ft);
  411. }
  412.  
  413. void sbstartwrite(ft) 
  414. ft_t ft;
  415. {
  416.     ft->info.size = BYTE;
  417.     ft->info.style = SIGN2;
  418.     rawstartwrite(ft);
  419.     rawdefaults(ft);
  420. }
  421.  
  422. void ubstartread(ft) 
  423. ft_t ft;
  424. {
  425.     ft->info.size = BYTE;
  426.     ft->info.style = UNSIGNED;
  427.     rawstartread(ft);
  428.     rawdefaults(ft);
  429. }
  430.  
  431. void ubstartwrite(ft) 
  432. ft_t ft;
  433. {
  434.     ft->info.size = BYTE;
  435.     ft->info.style = UNSIGNED;
  436.     rawstartwrite(ft);
  437.     rawdefaults(ft);
  438. }
  439.  
  440. void uwstartread(ft) 
  441. ft_t ft;
  442. {
  443.     ft->info.size = WORD;
  444.     ft->info.style = UNSIGNED;
  445.     rawstartread(ft);
  446.     rawdefaults(ft);
  447. }
  448.  
  449. void uwstartwrite(ft) 
  450. ft_t ft;
  451. {
  452.     ft->info.size = WORD;
  453.     ft->info.style = UNSIGNED;
  454.     rawstartwrite(ft);
  455.     rawdefaults(ft);
  456. }
  457.  
  458. void swstartread(ft) 
  459. ft_t ft;
  460. {
  461.     ft->info.size = WORD;
  462.     ft->info.style = SIGN2;
  463.     rawstartread(ft);
  464.     rawdefaults(ft);
  465. }
  466.  
  467. void swstartwrite(ft) 
  468. ft_t ft;
  469. {
  470.     ft->info.size = WORD;
  471.     ft->info.style = SIGN2;
  472.     rawstartwrite(ft);
  473.     rawdefaults(ft);
  474. }
  475.  
  476. void ulstartread(ft) 
  477. ft_t ft;
  478. {
  479.     ft->info.size = BYTE;
  480.     ft->info.style = ULAW;
  481.     rawstartread(ft);
  482.     rawdefaults(ft);
  483. }
  484.  
  485. void ulstartwrite(ft) 
  486. ft_t ft;
  487. {
  488.     ft->info.size = BYTE;
  489.     ft->info.style = ULAW;
  490.     rawstartwrite(ft);
  491.     rawdefaults(ft);
  492. }
  493.  
  494. void alstartread(ft) 
  495. ft_t ft;
  496. {
  497.     ft->info.size = BYTE;
  498.     ft->info.style = ALAW;
  499.     rawstartread(ft);
  500.     rawdefaults(ft);
  501. }
  502.  
  503. void alstartwrite(ft) 
  504. ft_t ft;
  505. {
  506.     ft->info.size = BYTE;
  507.     ft->info.style = ALAW;
  508.     rawstartwrite(ft);
  509.     rawdefaults(ft);
  510. }
  511.  
  512. void rawdefaults(ft)
  513. ft_t ft;
  514. {
  515.     if (ft->info.rate == 0)
  516.         ft->info.rate = 8000;
  517.     if (ft->info.channels == -1)
  518.         ft->info.channels = 1;
  519. }
  520.  
  521.  
  522.