Mercurial > mplayer.hg
annotate libaf/af_pan.c @ 32910:f34e21c5dc2f
Improve documentation on dlabel.
Throughout the skin documentation 'width' is used, so use it
instead of 'length' for the dlabel documentation, too.
Additionally, the German translation has been revised.
author | ib |
---|---|
date | Wed, 02 Mar 2011 13:30:44 +0000 |
parents | 8fa2f43cb760 |
children | a93891202051 |
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 * Copyright (C) 2002 Anders Johansson ajh@atri.curtin.edu.au |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
3 * |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
4 * This file is part of MPlayer. |
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 * 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
|
7 * 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
|
8 * 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
|
9 * (at your option) any later version. |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
10 * |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
11 * 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
|
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
14 * GNU General Public License for more details. |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
15 * |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
16 * 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
|
17 * 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
|
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
19 */ |
8607 | 20 |
21 #include <stdio.h> | |
22 #include <stdlib.h> | |
23 | |
24 #include <inttypes.h> | |
25 #include <math.h> | |
26 #include <limits.h> | |
27 | |
28 #include "af.h" | |
29 | |
30 // Data for specific instances of this filter | |
31 typedef struct af_pan_s | |
32 { | |
23532
a1eb547cf52e
Avoid zero output for pan filter; zero output now means same # of channels
zuxy
parents:
23531
diff
changeset
|
33 int nch; // Number of output channels; zero means same as input |
8607 | 34 float level[AF_NCH][AF_NCH]; // Gain level for each channel |
35 }af_pan_t; | |
36 | |
37 // Initialization and runtime control | |
38 static int control(struct af_instance_s* af, int cmd, void* arg) | |
39 { | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
40 af_pan_t* s = af->setup; |
8607 | 41 |
42 switch(cmd){ | |
43 case AF_CONTROL_REINIT: | |
44 // Sanity check | |
45 if(!arg) return AF_ERROR; | |
46 | |
47 af->data->rate = ((af_data_t*)arg)->rate; | |
14245 | 48 af->data->format = AF_FORMAT_FLOAT_NE; |
8607 | 49 af->data->bps = 4; |
23532
a1eb547cf52e
Avoid zero output for pan filter; zero output now means same # of channels
zuxy
parents:
23531
diff
changeset
|
50 af->data->nch = s->nch ? s->nch: ((af_data_t*)arg)->nch; |
24888 | 51 af->mul = (double)af->data->nch / ((af_data_t*)arg)->nch; |
8607 | 52 |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
53 if((af->data->format != ((af_data_t*)arg)->format) || |
8607 | 54 (af->data->bps != ((af_data_t*)arg)->bps)){ |
55 ((af_data_t*)arg)->format = af->data->format; | |
56 ((af_data_t*)arg)->bps = af->data->bps; | |
57 return AF_FALSE; | |
58 } | |
23532
a1eb547cf52e
Avoid zero output for pan filter; zero output now means same # of channels
zuxy
parents:
23531
diff
changeset
|
59 return AF_OK; |
8607 | 60 case AF_CONTROL_COMMAND_LINE:{ |
61 int nch = 0; | |
62 int n = 0; | |
63 char* cp = NULL; | |
64 int j,k; | |
65 // Read number of outputs | |
66 sscanf((char*)arg,"%i%n", &nch,&n); | |
67 if(AF_OK != control(af,AF_CONTROL_PAN_NOUT | AF_CONTROL_SET, &nch)) | |
68 return AF_ERROR; | |
69 | |
70 // Read pan values | |
71 cp = &((char*)arg)[n]; | |
72 j = 0; k = 0; | |
73 while((*cp == ':') && (k < AF_NCH)){ | |
16493
851d10933f27
Fix af_pan commandline mess and (hopefully) improve description.
reimar
parents:
14433
diff
changeset
|
74 sscanf(cp, ":%f%n" , &s->level[j][k], &n); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
75 mp_msg(MSGT_AFILTER, MSGL_V, "[pan] Pan level from channel %i to" |
16493
851d10933f27
Fix af_pan commandline mess and (hopefully) improve description.
reimar
parents:
14433
diff
changeset
|
76 " channel %i = %f\n",k,j,s->level[j][k]); |
8607 | 77 cp =&cp[n]; |
78 j++; | |
79 if(j>=nch){ | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
80 j = 0; |
8607 | 81 k++; |
82 } | |
83 } | |
84 return AF_OK; | |
85 } | |
86 case AF_CONTROL_PAN_LEVEL | AF_CONTROL_SET:{ | |
87 int i; | |
88 int ch = ((af_control_ext_t*)arg)->ch; | |
89 float* level = ((af_control_ext_t*)arg)->arg; | |
16493
851d10933f27
Fix af_pan commandline mess and (hopefully) improve description.
reimar
parents:
14433
diff
changeset
|
90 if (ch >= AF_NCH) |
851d10933f27
Fix af_pan commandline mess and (hopefully) improve description.
reimar
parents:
14433
diff
changeset
|
91 return AF_FALSE; |
8607 | 92 for(i=0;i<AF_NCH;i++) |
16493
851d10933f27
Fix af_pan commandline mess and (hopefully) improve description.
reimar
parents:
14433
diff
changeset
|
93 s->level[ch][i] = level[i]; |
8607 | 94 return AF_OK; |
95 } | |
96 case AF_CONTROL_PAN_LEVEL | AF_CONTROL_GET:{ | |
97 int i; | |
98 int ch = ((af_control_ext_t*)arg)->ch; | |
99 float* level = ((af_control_ext_t*)arg)->arg; | |
16493
851d10933f27
Fix af_pan commandline mess and (hopefully) improve description.
reimar
parents:
14433
diff
changeset
|
100 if (ch >= AF_NCH) |
851d10933f27
Fix af_pan commandline mess and (hopefully) improve description.
reimar
parents:
14433
diff
changeset
|
101 return AF_FALSE; |
8607 | 102 for(i=0;i<AF_NCH;i++) |
103 level[i] = s->level[ch][i]; | |
104 return AF_OK; | |
105 } | |
106 case AF_CONTROL_PAN_NOUT | AF_CONTROL_SET: | |
107 // Reinit must be called after this function has been called | |
108 | |
109 // Sanity check | |
12008 | 110 if(((int*)arg)[0] <= 0 || ((int*)arg)[0] > AF_NCH){ |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
111 mp_msg(MSGT_AFILTER, MSGL_ERR, "[pan] The number of output channels must be" |
8607 | 112 " between 1 and %i. Current value is %i\n",AF_NCH,((int*)arg)[0]); |
113 return AF_ERROR; | |
114 } | |
23532
a1eb547cf52e
Avoid zero output for pan filter; zero output now means same # of channels
zuxy
parents:
23531
diff
changeset
|
115 s->nch=((int*)arg)[0]; |
8607 | 116 return AF_OK; |
117 case AF_CONTROL_PAN_NOUT | AF_CONTROL_GET: | |
118 *(int*)arg = af->data->nch; | |
119 return AF_OK; | |
23551 | 120 case AF_CONTROL_PAN_BALANCE | AF_CONTROL_SET:{ |
121 float val = *(float*)arg; | |
122 if (s->nch) | |
123 return AF_ERROR; | |
124 if (af->data->nch >= 2) { | |
125 s->level[0][0] = min(1.f, 1.f - val); | |
126 s->level[0][1] = max(0.f, val); | |
127 s->level[1][0] = max(0.f, -val); | |
128 s->level[1][1] = min(1.f, 1.f + val); | |
129 } | |
130 return AF_OK; | |
131 } | |
132 case AF_CONTROL_PAN_BALANCE | AF_CONTROL_GET: | |
133 if (s->nch) | |
134 return AF_ERROR; | |
135 *(float*)arg = s->level[0][1] - s->level[1][0]; | |
136 return AF_OK; | |
8607 | 137 } |
138 return AF_UNKNOWN; | |
139 } | |
140 | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
141 // Deallocate memory |
8607 | 142 static void uninit(struct af_instance_s* af) |
143 { | |
22175
105f32787336
Fix nonsense tests ("if (af->data->audio)" before "if (af->data)").
uau
parents:
16493
diff
changeset
|
144 if(af->data) |
8674
93212da0032e
10l memory leak + bug fixes in ms to sample time conversion
anders
parents:
8607
diff
changeset
|
145 free(af->data->audio); |
22175
105f32787336
Fix nonsense tests ("if (af->data->audio)" before "if (af->data)").
uau
parents:
16493
diff
changeset
|
146 free(af->data); |
32537
8fa2f43cb760
Remove most of the NULL pointer check before free all over the code
cboesch
parents:
29263
diff
changeset
|
147 free(af->setup); |
8607 | 148 } |
149 | |
150 // Filter data through filter | |
151 static af_data_t* play(struct af_instance_s* af, af_data_t* data) | |
152 { | |
153 af_data_t* c = data; // Current working data | |
154 af_data_t* l = af->data; // Local data | |
155 af_pan_t* s = af->setup; // Setup for this instance | |
156 float* in = c->audio; // Input audio data | |
157 float* out = NULL; // Output audio data | |
158 float* end = in+c->len/4; // End of loop | |
159 int nchi = c->nch; // Number of input channels | |
160 int ncho = l->nch; // Number of output channels | |
161 register int j,k; | |
162 | |
163 if(AF_OK != RESIZE_LOCAL_BUFFER(af,data)) | |
164 return NULL; | |
165 | |
166 out = l->audio; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
167 // Execute panning |
8607 | 168 // FIXME: Too slow |
169 while(in < end){ | |
170 for(j=0;j<ncho;j++){ | |
171 register float x = 0.0; | |
172 register float* tin = in; | |
173 for(k=0;k<nchi;k++) | |
174 x += tin[k] * s->level[j][k]; | |
175 out[j] = x; | |
176 } | |
177 out+= ncho; | |
178 in+= nchi; | |
179 } | |
180 | |
181 // Set output data | |
182 c->audio = l->audio; | |
24888 | 183 c->len = c->len / c->nch * l->nch; |
8607 | 184 c->nch = l->nch; |
185 | |
186 return c; | |
187 } | |
188 | |
189 // 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:
22175
diff
changeset
|
190 static int af_open(af_instance_t* af){ |
8607 | 191 af->control=control; |
192 af->uninit=uninit; | |
193 af->play=play; | |
24888 | 194 af->mul=1; |
8607 | 195 af->data=calloc(1,sizeof(af_data_t)); |
196 af->setup=calloc(1,sizeof(af_pan_t)); | |
197 if(af->data == NULL || af->setup == NULL) | |
198 return AF_ERROR; | |
199 return AF_OK; | |
200 } | |
201 | |
202 // Description of this filter | |
203 af_info_t af_info_pan = { | |
204 "Panning audio filter", | |
205 "pan", | |
206 "Anders", | |
207 "", | |
23531
bd9e74cd4d3d
Make pan reentrant. Multiple pans in chain work fine.
zuxy
parents:
22748
diff
changeset
|
208 AF_FLAGS_REENTRANT, |
22746
fd6f824ef894
Rename open to af_open so as not to conflict with a previous header definition.
diego
parents:
22175
diff
changeset
|
209 af_open |
8607 | 210 }; |