Mercurial > mplayer.hg
annotate libaf/af_channels.c @ 36963:e539d330c7be
Remove unnecessary bounds checks in Win32 GUI.
The checks that the rendered potmeter button
doesn't exceed the bounds is not necessary as
the item value is already limited within the
range of 0 to 100.
Patch by Hans-Dieter Kosch, hdkosch kabelbw de.
author | ib |
---|---|
date | Mon, 24 Mar 2014 12:52:01 +0000 |
parents | 2b9bc3c2933d |
children |
rev | line source |
---|---|
28229
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
1 /* |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
2 * Audio filter that adds and removes channels, according to the |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
3 * command line parameter channels. It is stupid and can only add |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
4 * silence or copy channels, not mix or filter. |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
5 * |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
6 * This file is part of MPlayer. |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
7 * |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
8 * MPlayer is free software; you can redistribute it and/or modify |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
9 * it under the terms of the GNU General Public License as published by |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
10 * the Free Software Foundation; either version 2 of the License, or |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
11 * (at your option) any later version. |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
12 * |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
13 * MPlayer is distributed in the hope that it will be useful, |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
16 * GNU General Public License for more details. |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
17 * |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
18 * You should have received a copy of the GNU General Public License along |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
19 * with MPlayer; if not, write to the Free Software Foundation, Inc., |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
21 */ |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
22 |
7568 | 23 #include <stdio.h> |
24 #include <stdlib.h> | |
25 #include <string.h> | |
7975 | 26 #include <inttypes.h> |
7568 | 27 |
36395
2b9bc3c2933d
Remove some macros and switch to libavutil equivalents.
reimar
parents:
34174
diff
changeset
|
28 #include "libavutil/common.h" |
34174
a93891202051
Add missing mp_msg.h #includes, remove some unnecessary ones.
diego
parents:
29263
diff
changeset
|
29 #include "mp_msg.h" |
7568 | 30 #include "af.h" |
31 | |
8607 | 32 #define FR 0 |
33 #define TO 1 | |
34 | |
35 typedef struct af_channels_s{ | |
36 int route[AF_NCH][2]; | |
37 int nr; | |
38 int router; | |
39 }af_channels_t; | |
40 | |
7568 | 41 // Local function for copying data |
8711
906f7a2dc085
sig 11 fix in reinit and resample + spelling error fixes
anders
parents:
8607
diff
changeset
|
42 static void copy(void* in, void* out, int ins, int inos,int outs, int outos, int len, int bps) |
7568 | 43 { |
44 switch(bps){ | |
45 case 1:{ | |
46 int8_t* tin = (int8_t*)in; | |
47 int8_t* tout = (int8_t*)out; | |
48 tin += inos; | |
49 tout += outos; | |
50 len = len/ins; | |
51 while(len--){ | |
52 *tout=*tin; | |
53 tin +=ins; | |
54 tout+=outs; | |
55 } | |
56 break; | |
57 } | |
58 case 2:{ | |
59 int16_t* tin = (int16_t*)in; | |
60 int16_t* tout = (int16_t*)out; | |
61 tin += inos; | |
62 tout += outos; | |
63 len = len/(2*ins); | |
64 while(len--){ | |
65 *tout=*tin; | |
66 tin +=ins; | |
67 tout+=outs; | |
68 } | |
69 break; | |
70 } | |
12913 | 71 case 3:{ |
72 int8_t* tin = (int8_t*)in; | |
73 int8_t* tout = (int8_t*)out; | |
74 tin += 3 * inos; | |
75 tout += 3 * outos; | |
76 len = len / ( 3 * ins); | |
77 while (len--) { | |
78 tout[0] = tin[0]; | |
79 tout[1] = tin[1]; | |
80 tout[2] = tin[2]; | |
81 tin += 3 * ins; | |
82 tout += 3 * outs; | |
83 } | |
84 break; | |
85 } | |
7568 | 86 case 4:{ |
87 int32_t* tin = (int32_t*)in; | |
88 int32_t* tout = (int32_t*)out; | |
89 tin += inos; | |
90 tout += outos; | |
91 len = len/(4*ins); | |
92 while(len--){ | |
93 *tout=*tin; | |
94 tin +=ins; | |
95 tout+=outs; | |
96 } | |
97 break; | |
98 } | |
99 case 8:{ | |
100 int64_t* tin = (int64_t*)in; | |
101 int64_t* tout = (int64_t*)out; | |
102 tin += inos; | |
103 tout += outos; | |
104 len = len/(8*ins); | |
105 while(len--){ | |
106 *tout=*tin; | |
107 tin +=ins; | |
108 tout+=outs; | |
109 } | |
110 break; | |
111 } | |
112 default: | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
113 mp_msg(MSGT_AFILTER, MSGL_ERR, "[channels] Unsupported number of bytes/sample: %i" |
8607 | 114 " please report this error on the MPlayer mailing list. \n",bps); |
7568 | 115 } |
116 } | |
117 | |
8607 | 118 // Make sure the routes are sane |
119 static int check_routes(af_channels_t* s, int nin, int nout) | |
120 { | |
121 int i; | |
122 if((s->nr < 1) || (s->nr > AF_NCH)){ | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
123 mp_msg(MSGT_AFILTER, MSGL_ERR, "[channels] The number of routing pairs must be" |
8607 | 124 " between 1 and %i. Current value is %i\n",AF_NCH,s->nr); |
125 return AF_ERROR; | |
126 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
127 |
8607 | 128 for(i=0;i<s->nr;i++){ |
129 if((s->route[i][FR] >= nin) || (s->route[i][TO] >= nout)){ | |
29049 | 130 mp_msg(MSGT_AFILTER, MSGL_ERR, "[channels] Invalid routing in pair nr. %i.\n", i); |
8607 | 131 return AF_ERROR; |
132 } | |
133 } | |
134 return AF_OK; | |
135 } | |
136 | |
7568 | 137 // Initialization and runtime control |
138 static int control(struct af_instance_s* af, int cmd, void* arg) | |
139 { | |
8607 | 140 af_channels_t* s = af->setup; |
7568 | 141 switch(cmd){ |
142 case AF_CONTROL_REINIT: | |
8607 | 143 |
144 // Set default channel assignment | |
145 if(!s->router){ | |
146 int i; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
147 // Make sure this filter isn't redundant |
8607 | 148 if(af->data->nch == ((af_data_t*)arg)->nch) |
149 return AF_DETACH; | |
150 | |
151 // If mono: fake stereo | |
152 if(((af_data_t*)arg)->nch == 1){ | |
36395
2b9bc3c2933d
Remove some macros and switch to libavutil equivalents.
reimar
parents:
34174
diff
changeset
|
153 s->nr = FFMIN(af->data->nch,2); |
8607 | 154 for(i=0;i<s->nr;i++){ |
155 s->route[i][FR] = 0; | |
156 s->route[i][TO] = i; | |
157 } | |
158 } | |
159 else{ | |
36395
2b9bc3c2933d
Remove some macros and switch to libavutil equivalents.
reimar
parents:
34174
diff
changeset
|
160 s->nr = FFMIN(af->data->nch, ((af_data_t*)arg)->nch); |
8607 | 161 for(i=0;i<s->nr;i++){ |
162 s->route[i][FR] = i; | |
163 s->route[i][TO] = i; | |
164 } | |
165 } | |
166 } | |
7568 | 167 |
168 af->data->rate = ((af_data_t*)arg)->rate; | |
169 af->data->format = ((af_data_t*)arg)->format; | |
170 af->data->bps = ((af_data_t*)arg)->bps; | |
24888 | 171 af->mul = (double)af->data->nch / ((af_data_t*)arg)->nch; |
8607 | 172 return check_routes(s,((af_data_t*)arg)->nch,af->data->nch); |
7998
d48a06d07afb
Adding commandline options for filters and fixing stupid bug in cfg
anders
parents:
7975
diff
changeset
|
173 case AF_CONTROL_COMMAND_LINE:{ |
d48a06d07afb
Adding commandline options for filters and fixing stupid bug in cfg
anders
parents:
7975
diff
changeset
|
174 int nch = 0; |
8607 | 175 int n = 0; |
176 // Check number of channels and number of routing pairs | |
177 sscanf(arg, "%i:%i%n", &nch, &s->nr, &n); | |
178 | |
179 // If router scan commandline for routing pairs | |
180 if(s->nr){ | |
181 char* cp = &((char*)arg)[n]; | |
182 int ch = 0; | |
183 // Sanity check | |
184 if((s->nr < 1) || (s->nr > AF_NCH)){ | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
185 mp_msg(MSGT_AFILTER, MSGL_ERR, "[channels] The number of routing pairs must be" |
8607 | 186 " between 1 and %i. Current value is %i\n",AF_NCH,s->nr); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
187 } |
8607 | 188 s->router = 1; |
189 // Scan for pairs on commandline | |
190 while((*cp == ':') && (ch < s->nr)){ | |
191 sscanf(cp, ":%i:%i%n" ,&s->route[ch][FR], &s->route[ch][TO], &n); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
192 mp_msg(MSGT_AFILTER, MSGL_V, "[channels] Routing from channel %i to" |
8607 | 193 " channel %i\n",s->route[ch][FR],s->route[ch][TO]); |
194 cp = &cp[n]; | |
195 ch++; | |
196 } | |
197 } | |
198 | |
199 if(AF_OK != af->control(af,AF_CONTROL_CHANNELS | AF_CONTROL_SET ,&nch)) | |
200 return AF_ERROR; | |
201 return AF_OK; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
202 } |
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
203 case AF_CONTROL_CHANNELS | AF_CONTROL_SET: |
7568 | 204 // Reinit must be called after this function has been called |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
205 |
7568 | 206 // Sanity check |
12008 | 207 if(((int*)arg)[0] <= 0 || ((int*)arg)[0] > AF_NCH){ |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
208 mp_msg(MSGT_AFILTER, MSGL_ERR, "[channels] The number of output channels must be" |
8607 | 209 " between 1 and %i. Current value is %i\n",AF_NCH,((int*)arg)[0]); |
7568 | 210 return AF_ERROR; |
211 } | |
212 | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
213 af->data->nch=((int*)arg)[0]; |
8607 | 214 if(!s->router) |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
215 mp_msg(MSGT_AFILTER, MSGL_V, "[channels] Changing number of channels" |
8607 | 216 " to %i\n",af->data->nch); |
217 return AF_OK; | |
218 case AF_CONTROL_CHANNELS | AF_CONTROL_GET: | |
219 *(int*)arg = af->data->nch; | |
220 return AF_OK; | |
221 case AF_CONTROL_CHANNELS_ROUTING | AF_CONTROL_SET:{ | |
222 int ch = ((af_control_ext_t*)arg)->ch; | |
223 int* route = ((af_control_ext_t*)arg)->arg; | |
224 s->route[ch][FR] = route[FR]; | |
225 s->route[ch][TO] = route[TO]; | |
226 return AF_OK; | |
227 } | |
228 case AF_CONTROL_CHANNELS_ROUTING | AF_CONTROL_GET:{ | |
229 int ch = ((af_control_ext_t*)arg)->ch; | |
230 int* route = ((af_control_ext_t*)arg)->arg; | |
231 route[FR] = s->route[ch][FR]; | |
232 route[TO] = s->route[ch][TO]; | |
233 return AF_OK; | |
234 } | |
235 case AF_CONTROL_CHANNELS_NR | AF_CONTROL_SET: | |
236 s->nr = *(int*)arg; | |
237 return AF_OK; | |
238 case AF_CONTROL_CHANNELS_NR | AF_CONTROL_GET: | |
239 *(int*)arg = s->nr; | |
240 return AF_OK; | |
241 case AF_CONTROL_CHANNELS_ROUTER | AF_CONTROL_SET: | |
242 s->router = *(int*)arg; | |
243 return AF_OK; | |
244 case AF_CONTROL_CHANNELS_ROUTER | AF_CONTROL_GET: | |
245 *(int*)arg = s->router; | |
7568 | 246 return AF_OK; |
247 } | |
248 return AF_UNKNOWN; | |
249 } | |
250 | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
251 // Deallocate memory |
7568 | 252 static void uninit(struct af_instance_s* af) |
253 { | |
22179 | 254 free(af->setup); |
255 if (af->data) | |
256 free(af->data->audio); | |
257 free(af->data); | |
7568 | 258 } |
259 | |
260 // Filter data through filter | |
261 static af_data_t* play(struct af_instance_s* af, af_data_t* data) | |
262 { | |
8607 | 263 af_data_t* c = data; // Current working data |
264 af_data_t* l = af->data; // Local data | |
265 af_channels_t* s = af->setup; | |
266 int i; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
267 |
7568 | 268 if(AF_OK != RESIZE_LOCAL_BUFFER(af,data)) |
269 return NULL; | |
270 | |
8607 | 271 // Reset unused channels |
24888 | 272 memset(l->audio,0,c->len / c->nch * l->nch); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
273 |
8607 | 274 if(AF_OK == check_routes(s,c->nch,l->nch)) |
275 for(i=0;i<s->nr;i++) | |
276 copy(c->audio,l->audio,c->nch,s->route[i][FR], | |
277 l->nch,s->route[i][TO],c->len,c->bps); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
278 |
7568 | 279 // Set output data |
280 c->audio = l->audio; | |
24888 | 281 c->len = c->len / c->nch * l->nch; |
7568 | 282 c->nch = l->nch; |
283 | |
284 return c; | |
285 } | |
286 | |
287 // Allocate memory and set function pointers | |
22746
fd6f824ef894
Rename open to af_open so as not to conflict with a previous header definition.
diego
parents:
22179
diff
changeset
|
288 static int af_open(af_instance_t* af){ |
7568 | 289 af->control=control; |
290 af->uninit=uninit; | |
291 af->play=play; | |
24888 | 292 af->mul=1; |
7568 | 293 af->data=calloc(1,sizeof(af_data_t)); |
8607 | 294 af->setup=calloc(1,sizeof(af_channels_t)); |
295 if((af->data == NULL) || (af->setup == NULL)) | |
7568 | 296 return AF_ERROR; |
297 return AF_OK; | |
298 } | |
299 | |
300 // Description of this filter | |
301 af_info_t af_info_channels = { | |
302 "Insert or remove channels", | |
303 "channels", | |
304 "Anders", | |
305 "", | |
7615 | 306 AF_FLAGS_REENTRANT, |
22746
fd6f824ef894
Rename open to af_open so as not to conflict with a previous header definition.
diego
parents:
22179
diff
changeset
|
307 af_open |
7568 | 308 }; |