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

  1. /*
  2.  * swap - effect to swap ordering of channels in multi-channel audio.
  3.  *
  4.  * Written by Chris Bagwell (cbagwell@sprynet.com) - March 16, 1999
  5.  *
  6.   * Copyright 1999 Chris Bagwell And Sundry Contributors
  7.  * This source code is freely redistributable and may be used for
  8.  * any purpose.  This copyright notice must be maintained. 
  9.  * Chris Bagwell And Sundry Contributors are not responsible for 
  10.  * the consequences of using this software.
  11.  */
  12.  
  13.  
  14. #include "st.h"
  15.  
  16. /* Private data for SKEL file */
  17. typedef struct swapstuff {
  18.     int        order[4];
  19. } *swap_t;
  20.  
  21. /*
  22.  * Process options
  23.  *
  24.  * Don't do initialization now.
  25.  * The 'info' fields are not yet filled in.
  26.  */
  27. void swap_getopts(effp, n, argv) 
  28. eff_t effp;
  29. int n;
  30. char **argv;
  31. {
  32.     swap_t swap = (swap_t) effp->priv;
  33.  
  34.     swap->order[0] = swap->order[1] = swap->order[2] = swap->order[3] = 0;
  35.     if (n)
  36.     {
  37.     if (n != 4)
  38.     {
  39.         fail("Usage: swap [1 2 3 4]");
  40.     }
  41.     else
  42.     {
  43.         sscanf(argv[0],"%d",&swap->order[0]);
  44.         sscanf(argv[1],"%d",&swap->order[1]);
  45.         sscanf(argv[2],"%d",&swap->order[2]);
  46.         sscanf(argv[3],"%d",&swap->order[3]);
  47.     }
  48.     }
  49. }
  50.  
  51. /*
  52.  * Prepare processing.
  53.  * Do all initializations.
  54.  */
  55. void swap_start(effp)
  56. eff_t effp;
  57. {
  58.     if (effp->outinfo.channels == 1)
  59.     fail("Can't swap channels on mono data.");
  60. }
  61.  
  62. /*
  63.  * Processed signed long samples from ibuf to obuf.
  64.  * Return number of samples processed.
  65.  */
  66.  
  67. void swap_flow(effp, ibuf, obuf, isamp, osamp)
  68. eff_t effp;
  69. LONG *ibuf, *obuf;
  70. int *isamp, *osamp;
  71. {
  72.     swap_t swap = (swap_t) effp->priv;
  73.     int len, done;
  74.  
  75.     switch (effp->outinfo.channels)
  76.     {
  77.     case 2:
  78.     /* Length to process will be buffer length / 2 since we
  79.      * work with two samples at a time.
  80.      */
  81.     len = ((*isamp > *osamp) ? *osamp : *isamp) / 2;
  82.     for(done = 0; done < len; done++)
  83.     {
  84.         obuf[0] = ibuf[1];
  85.         obuf[1] = ibuf[0];
  86.         /* Advance buffer by 2 samples */
  87.         ibuf += 2;
  88.         obuf += 2;
  89.     }
  90.     
  91.     *isamp = len * 2;
  92.     *osamp = len * 2;
  93.     
  94.     break;
  95.     
  96.     case 4:
  97.     /* If nothing set then default to the following order */
  98.     if (!swap->order[0] && !swap->order[1] &&
  99.         !swap->order[2] && !swap->order[3])
  100.     {
  101.         swap->order[0] = 1;
  102.         swap->order[1] = 0;
  103.         swap->order[2] = 3;
  104.         swap->order[3] = 2;
  105.     }
  106.     /* Length to process will be buffer length / 4 since we
  107.      * work with four samples at a time.
  108.      */
  109.     len = ((*isamp > *osamp) ? *osamp : *isamp) / 4;
  110.     for(done = 0; done < len; done++)
  111.     {
  112.         obuf[0] = ibuf[swap->order[0]];
  113.         obuf[1] = ibuf[swap->order[1]];
  114.         obuf[2] = ibuf[swap->order[2]];
  115.         obuf[3] = ibuf[swap->order[3]];
  116.         /* Advance buffer by 2 samples */
  117.         ibuf += 4;
  118.         obuf += 4;
  119.     }
  120.     *isamp = len * 4;
  121.     *osamp = len * 4;
  122.     
  123.     break;
  124.     }
  125. }
  126.  
  127. /*
  128.  * Drain out remaining samples if the effect generates any.
  129.  */
  130.  
  131. void swap_drain(effp, obuf, osamp)
  132. LONG *obuf;
  133. int *osamp;
  134. {
  135.     *osamp = 0;
  136. }
  137.  
  138. /*
  139.  * Do anything required when you stop reading samples.  
  140.  *    (free allocated memory, etc.)
  141.  */
  142. void swap_stop(effp)
  143. eff_t effp;
  144. {
  145.     /* nothing to do */
  146. }
  147.