File: pick.c

package info (click to toggle)
sox 12.16-6
  • links: PTS
  • area: main
  • in suites: potato
  • size: 1,180 kB
  • ctags: 1,466
  • sloc: ansic: 16,658; sh: 2,071; makefile: 126
file content (139 lines) | stat: -rw-r--r-- 3,277 bytes parent folder | download | duplicates (2)
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.
 */

void 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! 
 */
void pick_stop(effp)
eff_t effp;
{
	/* nothing to do */
}