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

  1.  
  2. /*
  3.  * July 5, 1991
  4.  * Copyright 1991 Lance Norskog And Sundry Contributors
  5.  * This source code is freely redistributable and may be used for
  6.  * any purpose.  This copyright notice must be maintained. 
  7.  * Lance Norskog And Sundry Contributors are not responsible for 
  8.  * the consequences of using this software.
  9.  *
  10.  * Channel duplication code by Graeme W. Gill - 93/5/18
  11.  */
  12.  
  13. /*
  14.  * Sound Tools stereo/quad -> mono mixdown effect file.
  15.  * and mono/stereo -> stereo/quad channel duplication.
  16.  *
  17.  * What's in a center channel?
  18.  */
  19.  
  20. #include "st.h"
  21.  
  22. /* Private data for SKEL file */
  23. typedef struct avgstuff {
  24.     int    mix;            /* How are we mixing it? */
  25. } *avg_t;
  26.  
  27. #define MIX_CENTER    0
  28. #define MIX_LEFT    1
  29. #define MIX_RIGHT    2
  30.  
  31. /*
  32.  * Process options
  33.  */
  34. void avg_getopts(effp, n, argv) 
  35. eff_t effp;
  36. int n;
  37. char **argv;
  38. {
  39.     avg_t avg = (avg_t) effp->priv;
  40.  
  41.     /* NOTE :- should probably have a pan option for both */
  42.     /* 2 -> 1 and 1 -> 2 etc. conversion, rather than just */
  43.     /* left and right. If 4 channels is to be fully supported, */
  44.     /* front and back pan is also needed. (GWG) */
  45.     /* (should  at least have MIX_FRONT and MIX_BACK) */
  46.     avg->mix = MIX_CENTER;
  47.     if (n) {
  48.         if(!strcmp(argv[0], "-l"))
  49.             avg->mix = MIX_LEFT;
  50.         else if (!strcmp(argv[0], "-r"))
  51.             avg->mix = MIX_RIGHT;
  52.         else
  53.             fail("Usage: avg [ -l | -r ]");
  54.     }
  55. }
  56.  
  57. /*
  58.  * Start processing
  59.  */
  60. void
  61. avg_start(effp)
  62. eff_t effp;
  63. {
  64.     switch (effp->outinfo.channels) 
  65.     {
  66.     case 1: switch (effp->ininfo.channels) 
  67.         {
  68.         case 2: 
  69.         case 4:
  70.             return;
  71.         default:
  72.             break;
  73.         }
  74.         break;
  75.     case 2: switch (effp->ininfo.channels) 
  76.         {
  77.         case 1:
  78.         case 4:
  79.             return;
  80.         default:
  81.             break;
  82.         }
  83.         break;
  84.     case 4: switch (effp->ininfo.channels) 
  85.         {
  86.         case 1:
  87.         case 2:
  88.             return;
  89.         default:
  90.             break;
  91.         }
  92.     default:
  93.         break;
  94.     }    
  95.     fail("Can't average %d channels into %d channels",
  96.         effp->ininfo.channels, effp->outinfo.channels);
  97. }
  98.  
  99. /*
  100.  * Process either isamp or osamp samples, whichever is smaller.
  101.  */
  102.  
  103. void avg_flow(effp, ibuf, obuf, isamp, osamp)
  104. eff_t effp;
  105. LONG *ibuf, *obuf;
  106. int *isamp, *osamp;
  107. {
  108.     avg_t avg = (avg_t) effp->priv;
  109.     int len, done;
  110.     
  111.     switch (effp->outinfo.channels) {
  112.         case 1: switch (effp->ininfo.channels) {
  113.             case 2:
  114.                 /* average 2 channels into 1 */
  115.                 len = ((*isamp/2 > *osamp) ? *osamp : *isamp/2);
  116.                 switch(avg->mix) {
  117.                     case MIX_CENTER:
  118.                     for(done = 0; done < len; done++) {
  119.                         *obuf++ = ibuf[0]/2 + ibuf[1]/2;
  120.                         ibuf += 2;
  121.                     }
  122.                     break;
  123.                     case MIX_LEFT:
  124.                     for(done = 0; done < len; done++) {
  125.                         *obuf++ = ibuf[0];
  126.                         ibuf += 2;
  127.                     }
  128.                     break;
  129.                     case MIX_RIGHT:
  130.                     for(done = 0; done < len; done++) {
  131.                         *obuf++ = ibuf[1];
  132.                         ibuf += 2;
  133.                     }
  134.                     break;
  135.                 }
  136.                 *isamp = len * 2;
  137.                 *osamp = len;
  138.                 break;
  139.             case 4:
  140.                 /* average 4 channels into 1 */
  141.                 len = ((*isamp/4 > *osamp) ? *osamp : *isamp/4);
  142.                 switch(avg->mix) {
  143.                     case MIX_CENTER:
  144.                     for(done = 0; done < len; done++) {
  145.                         *obuf++ = ibuf[0]/4 + ibuf[1]/4 +
  146.                             ibuf[2]/4 + ibuf[3]/4;
  147.                         ibuf += 4;
  148.                     }
  149.                     break;
  150.                     case MIX_LEFT:
  151.                     for(done = 0; done < len; done++) {
  152.                         *obuf++ = ibuf[0]/2 + ibuf[2]/2;
  153.                         ibuf += 4;
  154.                     }
  155.                     break;
  156.                     case MIX_RIGHT:
  157.                     for(done = 0; done < len; done++) {
  158.                         *obuf++ = ibuf[1]/2 + ibuf[3]/2;
  159.                         ibuf += 4;
  160.                     }
  161.                     break;
  162.                 }
  163.                 *isamp = len * 4;
  164.                 *osamp = len;
  165.                 break;
  166.             }
  167.             break;
  168.         case 2: switch (effp->ininfo.channels) {
  169.             case 1:
  170.                 /* duplicate 1 channel into 2 */
  171.                 len = ((*isamp > *osamp/2) ? *osamp/2 : *isamp);
  172.                 switch(avg->mix) {
  173.                     case MIX_CENTER:
  174.                     for(done = 0; done < len; done++) {
  175.                         obuf[0] = obuf[1] = ibuf[0];
  176.                         ibuf += 1;
  177.                         obuf += 2;
  178.                     }
  179.                     break;
  180.                     case MIX_LEFT:
  181.                     for(done = 0; done < len; done++) {
  182.                         obuf[0] = ibuf[0];
  183.                         obuf[1] = 0;
  184.                         ibuf += 1;
  185.                         obuf += 2;
  186.                     }
  187.                     break;
  188.                     case MIX_RIGHT:
  189.                     for(done = 0; done < len; done++) {
  190.                         obuf[0] = 0;
  191.                         obuf[1] = ibuf[0];
  192.                         ibuf += 1;
  193.                         obuf += 2;
  194.                     }
  195.                     break;
  196.                 }
  197.                 *isamp = len;
  198.                 *osamp = len * 2;
  199.                 break;
  200.             /*
  201.              * After careful inspection of CSOUND source code,
  202.              * I'm mildly sure the order is:
  203.              *     front-left, front-right, rear-left, rear-right
  204.              */
  205.             case 4:
  206.                 /* average 4 channels into 2 */
  207.                 len = ((*isamp/4 > *osamp/2) ? *osamp/2 : *isamp/4);
  208.                 for(done = 0; done < len; done++) {
  209.                     obuf[0] = ibuf[0]/2 + ibuf[2]/2;
  210.                     obuf[1] = ibuf[1]/2 + ibuf[3]/2;
  211.                     ibuf += 4;
  212.                     obuf += 2;
  213.                 }
  214.                 *isamp = len * 4;
  215.                 *osamp = len * 2;
  216.                 break;
  217.             }
  218.             break;
  219.         case 4: switch (effp->ininfo.channels) {
  220.             case 1:
  221.                 /* duplicate 1 channel into 4 */
  222.                 len = ((*isamp > *osamp/4) ? *osamp/4 : *isamp);
  223.                 switch(avg->mix) {
  224.                     case MIX_CENTER:
  225.                     for(done = 0; done < len; done++) {
  226.                         obuf[0] = obuf[1] = 
  227.                         obuf[2] = obuf[3] = ibuf[0];
  228.                         ibuf += 1;
  229.                         obuf += 4;
  230.                     }
  231.                     break;
  232.                     case MIX_LEFT:
  233.                     for(done = 0; done < len; done++) {
  234.                         obuf[0] = obuf[2] = ibuf[0];
  235.                         obuf[1] = obuf[3] = 0;
  236.                         ibuf += 1;
  237.                         obuf += 4;
  238.                     }
  239.                     break;
  240.                     case MIX_RIGHT:
  241.                     for(done = 0; done < len; done++) {
  242.                         obuf[0] = obuf[2] = 0;
  243.                         obuf[1] = obuf[3] = ibuf[0];
  244.                         ibuf += 1;
  245.                         obuf += 4;
  246.                     }
  247.                     break;
  248.                 }
  249.                 *isamp = len;
  250.                 *osamp = len * 4;
  251.                 break;
  252.             case 2:
  253.                 /* duplicate 2 channels into 4 */
  254.                 len = ((*isamp/2 > *osamp/4) ? *osamp/4 : *isamp/2);
  255.                 for(done = 0; done < len; done++) {
  256.                     obuf[0] = obuf[2] = ibuf[0];
  257.                     obuf[1] = obuf[3] = ibuf[1];
  258.                     ibuf += 2;
  259.                     obuf += 4;
  260.                 }
  261.                 *isamp = len * 2;
  262.                 *osamp = len * 4;
  263.                 break;
  264.             }
  265.             break;
  266.     }    /* end switch out channels */
  267. }
  268.  
  269. /*
  270.  * Do anything required when you stop reading samples.  
  271.  * Don't close input file! 
  272.  *
  273.  * Should have statistics on right, left, and output amplitudes.
  274.  */
  275. void avg_stop(effp)
  276. eff_t effp;
  277. {
  278.     /* nothing to do */
  279. }
  280.  
  281.