Mercurial > mplayer.hg
annotate libaf/af_delay.c @ 28677:cd9aa9b2533a
ffvc1vdpau and ffwmv3vdpau should be marked as buggy in the same
way as the software decoders, otherwise they will be preferred over
the software decoders which just breaks things when using e.g. xv vo.
author | reimar |
---|---|
date | Mon, 23 Feb 2009 11:48:45 +0000 |
parents | 72d0b1444141 |
children | 8c706ce21c6f |
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 * This audio filter delays the output signal for the different |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
3 * channels and can be used for simple position panning. |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
24888
diff
changeset
|
4 * An extension for this filter would be a reverb. |
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> | |
8698 | 26 #include <inttypes.h> |
7568 | 27 |
28 #include "af.h" | |
29 | |
8675
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
30 #define L 65536 |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
31 |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
32 #define UPDATEQI(qi) qi=(qi+1)&(L-1) |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
33 |
7568 | 34 // Data for specific instances of this filter |
35 typedef struct af_delay_s | |
36 { | |
8675
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
37 void* q[AF_NCH]; // Circular queues used for delaying audio signal |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
38 int wi[AF_NCH]; // Write index |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
39 int ri; // Read index |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
40 float d[AF_NCH]; // Delay [ms] |
7568 | 41 }af_delay_t; |
42 | |
43 // Initialization and runtime control | |
44 static int control(struct af_instance_s* af, int cmd, void* arg) | |
45 { | |
8675
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
46 af_delay_t* s = af->setup; |
7568 | 47 switch(cmd){ |
48 case AF_CONTROL_REINIT:{ | |
8675
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
49 int i; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
50 |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
51 // Free prevous delay queues |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
52 for(i=0;i<af->data->nch;i++){ |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
53 if(s->q[i]) |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
54 free(s->q[i]); |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
55 } |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
56 |
7568 | 57 af->data->rate = ((af_data_t*)arg)->rate; |
58 af->data->nch = ((af_data_t*)arg)->nch; | |
59 af->data->format = ((af_data_t*)arg)->format; | |
60 af->data->bps = ((af_data_t*)arg)->bps; | |
61 | |
8675
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
62 // Allocate new delay queues |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
63 for(i=0;i<af->data->nch;i++){ |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
64 s->q[i] = calloc(L,af->data->bps); |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
65 if(NULL == s->q[i]) |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
66 af_msg(AF_MSG_FATAL,"[delay] Out of memory\n"); |
7568 | 67 } |
68 | |
8675
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
69 return control(af,AF_CONTROL_DELAY_LEN | AF_CONTROL_SET,s->d); |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
70 } |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
71 case AF_CONTROL_COMMAND_LINE:{ |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
72 int n = 1; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
73 int i = 0; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
74 char* cl = arg; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
75 while(n && i < AF_NCH ){ |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
76 sscanf(cl,"%f:%n",&s->d[i],&n); |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
77 if(n==0 || cl[n-1] == '\0') |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
78 break; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
79 cl=&cl[n]; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
80 i++; |
7568 | 81 } |
82 return AF_OK; | |
83 } | |
8675
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
84 case AF_CONTROL_DELAY_LEN | AF_CONTROL_SET:{ |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
85 int i; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
86 if(AF_OK != af_from_ms(AF_NCH, arg, s->wi, af->data->rate, 0.0, 1000.0)) |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
87 return AF_ERROR; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
88 s->ri = 0; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
89 for(i=0;i<AF_NCH;i++){ |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
90 af_msg(AF_MSG_DEBUG0,"[delay] Channel %i delayed by %0.3fms\n", |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
91 i,clamp(s->d[i],0.0,1000.0)); |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
92 af_msg(AF_MSG_DEBUG1,"[delay] Channel %i delayed by %i samples\n", |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
93 i,s->wi[i]); |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
94 } |
8607 | 95 return AF_OK; |
7568 | 96 } |
8675
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
97 case AF_CONTROL_DELAY_LEN | AF_CONTROL_GET:{ |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
98 int i; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
99 for(i=0;i<AF_NCH;i++){ |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
100 if(s->ri > s->wi[i]) |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
101 s->wi[i] = L - (s->ri - s->wi[i]); |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
102 else |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
103 s->wi[i] = s->wi[i] - s->ri; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
104 } |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
105 return af_to_ms(AF_NCH, s->wi, arg, af->data->rate); |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
106 } |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
107 } |
7568 | 108 return AF_UNKNOWN; |
109 } | |
110 | |
111 // Deallocate memory | |
112 static void uninit(struct af_instance_s* af) | |
113 { | |
8675
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
114 int i; |
7568 | 115 if(af->data) |
116 free(af->data); | |
8675
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
117 for(i=0;i<AF_NCH;i++) |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
118 if(((af_delay_t*)(af->setup))->q[i]) |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
119 free(((af_delay_t*)(af->setup))->q[i]); |
7568 | 120 if(af->setup) |
121 free(af->setup); | |
122 } | |
123 | |
124 // Filter data through filter | |
125 static af_data_t* play(struct af_instance_s* af, af_data_t* data) | |
126 { | |
8675
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
127 af_data_t* c = data; // Current working data |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
128 af_delay_t* s = af->setup; // Setup for this instance |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
129 int nch = c->nch; // Number of channels |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
130 int len = c->len/c->bps; // Number of sample in data chunk |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
131 int ri = 0; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
132 int ch,i; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
133 for(ch=0;ch<nch;ch++){ |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
134 switch(c->bps){ |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
135 case 1:{ |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
136 int8_t* a = c->audio; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
137 int8_t* q = s->q[ch]; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
138 int wi = s->wi[ch]; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
139 ri = s->ri; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
140 for(i=ch;i<len;i+=nch){ |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
141 q[wi] = a[i]; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
142 a[i] = q[ri]; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
143 UPDATEQI(wi); |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
144 UPDATEQI(ri); |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
145 } |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
146 s->wi[ch] = wi; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
147 break; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
148 } |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
149 case 2:{ |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
150 int16_t* a = c->audio; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
151 int16_t* q = s->q[ch]; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
152 int wi = s->wi[ch]; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
153 ri = s->ri; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
154 for(i=ch;i<len;i+=nch){ |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
155 q[wi] = a[i]; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
156 a[i] = q[ri]; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
157 UPDATEQI(wi); |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
158 UPDATEQI(ri); |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
159 } |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
160 s->wi[ch] = wi; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
161 break; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
162 } |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
163 case 4:{ |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
164 int32_t* a = c->audio; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
165 int32_t* q = s->q[ch]; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
166 int wi = s->wi[ch]; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
167 ri = s->ri; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
168 for(i=ch;i<len;i+=nch){ |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
169 q[wi] = a[i]; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
170 a[i] = q[ri]; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
171 UPDATEQI(wi); |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
172 UPDATEQI(ri); |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
173 } |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
174 s->wi[ch] = wi; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
175 break; |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
176 } |
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
177 } |
7568 | 178 } |
8675
54c386615a70
Extending delay to have different delays for different channels
anders
parents:
8607
diff
changeset
|
179 s->ri = ri; |
7568 | 180 return c; |
181 } | |
182 | |
183 // 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:
8698
diff
changeset
|
184 static int af_open(af_instance_t* af){ |
7568 | 185 af->control=control; |
186 af->uninit=uninit; | |
187 af->play=play; | |
24888 | 188 af->mul=1; |
7568 | 189 af->data=calloc(1,sizeof(af_data_t)); |
190 af->setup=calloc(1,sizeof(af_delay_t)); | |
191 if(af->data == NULL || af->setup == NULL) | |
192 return AF_ERROR; | |
193 return AF_OK; | |
194 } | |
195 | |
196 // Description of this filter | |
197 af_info_t af_info_delay = { | |
198 "Delay audio filter", | |
199 "delay", | |
200 "Anders", | |
201 "", | |
7615 | 202 AF_FLAGS_REENTRANT, |
22746
fd6f824ef894
Rename open to af_open so as not to conflict with a previous header definition.
diego
parents:
8698
diff
changeset
|
203 af_open |
7568 | 204 }; |
205 | |
206 |