home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 3 / AACD03.BIN / AACD / Sound / SoX / Source / pick.c < prev    next >
C/C++ Source or Header  |  1999-07-18  |  3KB  |  140 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.  
  11. /*
  12.  *  "pick" effect by Lauren Weinstein (lauren@vortex.com); 2/94
  13.  *  Creates a 1 channel file by selecting a single channel from
  14.  *  a 2 or 4 channel file.  Does not currently allow creating a 2 channel
  15.  *  file by selecting 2 channels from a 4 channel file.
  16.  */
  17.  
  18. #include "st.h"
  19. #include "libst.h"
  20.  
  21. /* Private data for SKEL file */
  22. typedef struct pickstuff {
  23.     int    chan;     /* selected channel */
  24. } *pick_t;
  25.  
  26. /* channel names are offset by 1 from actual channel byte array offsets */
  27. #define CHAN_1    0    
  28. #define CHAN_2    1
  29. #define CHAN_3    2
  30. #define CHAN_4    3
  31.  
  32. /*
  33.  * Process options
  34.  */
  35. void
  36. pick_getopts(effp, n, argv) 
  37. eff_t effp;
  38. int n;
  39. char **argv;
  40. {
  41.     pick_t pick = (pick_t) effp->priv;
  42.  
  43.     if (n == 1 && argv[0][0] == '-') {  /* must specify channel to pick */
  44.         switch (argv[0][1]) {
  45.             case 'l':
  46.                 pick->chan = CHAN_1;
  47.                 return;
  48.             case 'r':
  49.                 pick->chan = CHAN_2;
  50.                 return;
  51.             case '1':
  52.                 pick->chan = CHAN_1;
  53.                 return;
  54.             case '2':
  55.                 pick->chan = CHAN_2;
  56.                 return;
  57.             case '3':
  58.                 pick->chan = CHAN_3;
  59.                 return;
  60.             case '4':
  61.                 pick->chan = CHAN_4;
  62.                 return;
  63.         }
  64.     }
  65.     pick->chan = -1;  /* invalid option */
  66. }
  67.  
  68.  
  69. /*
  70.  * Start processing.  Final option checking is done here since
  71.  * error/usage messages will vary based on the number of input/output
  72.  * channels selected, and that info is not available in pick_getopts()
  73.  * above.
  74.  */
  75. void
  76. pick_start(effp)
  77. eff_t effp;
  78. {
  79.     pick_t pick = (pick_t) effp->priv;
  80.  
  81.     if (effp->outinfo.channels != 1)  /* must be one output channel */
  82.        fail("Can't pick with other than 1 output channel."); 
  83.     if (effp->ininfo.channels != 2 && effp->ininfo.channels != 4)
  84.             fail("Can't pick with other than 2 or 4 input channels.");
  85.         if (effp->ininfo.channels == 2) {  /* check for valid option */
  86.        if (pick->chan == -1 || pick->chan == CHAN_3 || pick->chan == CHAN_4)
  87.              fail("Must specify channel to pick: '-l', '-r', '-1', or '-2'.");
  88.     }
  89.     else  /* must be 4 channels; check for valid option */
  90.        if (pick->chan == -1)
  91.           fail("Must specify channel to pick: '-1', '-2', '-3', or '-4'.");
  92. }
  93.  
  94. /*
  95.  * Process signed long samples from ibuf to obuf,
  96.  * isamp or osamp samples, whichever is smaller,
  97.  * while picking appropriate channels.
  98.  */
  99.  
  100. void pick_flow(effp, ibuf, obuf, isamp, osamp)
  101. eff_t effp;
  102. LONG *ibuf, *obuf;
  103. int *isamp, *osamp;
  104. {
  105.     pick_t pick = (pick_t) effp->priv;
  106.     int len, done;
  107.     
  108.     switch (effp->ininfo.channels) {
  109.         case 2:
  110.             len = ((*isamp/2 > *osamp) ? *osamp : *isamp/2);
  111.             for(done = 0; done < len; done++) {
  112.                 *obuf++ = ibuf[pick->chan];
  113.                 ibuf += 2;
  114.             }
  115.             *isamp = len * 2;
  116.             *osamp = len;
  117.             break;
  118.         case 4:
  119.             len = ((*isamp/4 > *osamp) ? *osamp : *isamp/4);
  120.             for(done = 0; done < len; done++) {
  121.                 *obuf++ = ibuf[pick->chan];
  122.                 ibuf += 4;
  123.             }
  124.             *isamp = len * 4;
  125.             *osamp = len;
  126.             break;
  127.     }
  128. }
  129.  
  130. /*
  131.  * Do anything required when you stop reading samples.  
  132.  * Don't close input file! 
  133.  */
  134. void pick_stop(effp)
  135. eff_t effp;
  136. {
  137.     /* nothing to do */
  138. }
  139.  
  140.