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