1 /*
2 * Copyright (c) 2013 Paul B Mahol
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 /**
22 * @file
23 * phaser audio filter
24 */
25
31
36 };
37
44
46
49
52
54
57 int nb_samples, int channels);
59
60 #define OFFSET(x) offsetof(AudioPhaserContext, x)
61 #define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
62
74 { NULL }
75 };
76
78
80 {
82
87
88 return 0;
89 }
90
92 {
101 };
102
104 if (!layouts)
107
109 if (!formats)
112
114 if (!formats)
117
118 return 0;
119 }
120
122 void *
table,
int table_size,
123 double min,
double max,
double phase)
124 {
125 uint32_t i, phase_offset = phase /
M_PI / 2 * table_size + 0.5;
126
127 for (i = 0; i < table_size; i++) {
128 uint32_t point = (i + phase_offset) % table_size;
129 double d;
130
131 switch (wave_type) {
133 d = (sin((
double)point / table_size * 2 *
M_PI) + 1) / 2;
134 break;
136 d = (double)point * 2 / table_size;
137 switch (4 * point / table_size) {
138 case 0: d = d + 0.5; break;
139 case 1:
140 case 2: d = 1.5 - d; break;
141 case 3: d = d - 1.5; break;
142 }
143 break;
144 default:
146 }
147
148 d = d * (max -
min) + min;
149 switch (sample_fmt) {
151 float *
fp = (
float *)table;
152 *fp++ = (float)d;
154 continue; }
156 double *dp = (double *)table;
157 *dp++ = d;
158 table = dp;
159 continue; }
160 }
161
162 d += d < 0 ? -0.5 : 0.5;
163 switch (sample_fmt) {
166 *sp++ = (int16_t)d;
168 continue; }
172 table = ip;
173 continue; }
174 default:
176 }
177 }
178 }
179
180 #define MOD(a, b) (((a) >= (b)) ? (a) - (b) : (a))
181
182 #define PHASER_PLANAR(name, type) \
183 static void phaser_## name ##p(AudioPhaserContext *p, \
184 uint8_t * const *src, uint8_t **dst, \
185 int nb_samples, int channels) \
186 { \
187 int i, c, delay_pos, modulation_pos; \
188 \
189 av_assert0(channels > 0); \
190 for (c = 0; c < channels; c++) { \
191 type *s = (type *)src[c]; \
192 type *d = (type *)dst[c]; \
193 double *buffer = p->delay_buffer + \
194 c * p->delay_buffer_length; \
195 \
196 delay_pos = p->delay_pos; \
197 modulation_pos = p->modulation_pos; \
198 \
199 for (i = 0; i < nb_samples; i++, s++, d++) { \
200 double v = *s * p->in_gain + buffer[ \
201 MOD(delay_pos + p->modulation_buffer[ \
202 modulation_pos], \
203 p->delay_buffer_length)] * p->decay; \
204 \
205 modulation_pos = MOD(modulation_pos + 1, \
206 p->modulation_buffer_length); \
207 delay_pos = MOD(delay_pos + 1, p->delay_buffer_length); \
208 buffer[delay_pos] = v; \
209 \
210 *d = v * p->out_gain; \
211 } \
212 } \
213 \
214 p->delay_pos = delay_pos; \
215 p->modulation_pos = modulation_pos; \
216 }
217
218 #define PHASER(name, type) \
219 static void phaser_## name (AudioPhaserContext *p, \
220 uint8_t * const *src, uint8_t **dst, \
221 int nb_samples, int channels) \
222 { \
223 int i, c, delay_pos, modulation_pos; \
224 type *s = (type *)src[0]; \
225 type *d = (type *)dst[0]; \
226 double *buffer = p->delay_buffer; \
227 \
228 delay_pos = p->delay_pos; \
229 modulation_pos = p->modulation_pos; \
230 \
231 for (i = 0; i < nb_samples; i++) { \
232 int pos = MOD(delay_pos + p->modulation_buffer[modulation_pos], \
233 p->delay_buffer_length) * channels; \
234 int npos; \
235 \
236 delay_pos = MOD(delay_pos + 1, p->delay_buffer_length); \
237 npos = delay_pos * channels; \
238 for (c = 0; c < channels; c++, s++, d++) { \
239 double v = *s * p->in_gain + buffer[pos + c] * p->decay; \
240 \
241 buffer[npos + c] = v; \
242 \
243 *d = v * p->out_gain; \
244 } \
245 \
246 modulation_pos = MOD(modulation_pos + 1, \
247 p->modulation_buffer_length); \
248 } \
249 \
250 p->delay_pos = delay_pos; \
251 p->modulation_pos = modulation_pos; \
252 }
253
258
263
265 {
268
273
276
280
282
293 }
294
295 return 0;
296 }
297
299 {
303
305 outbuf = inbuf;
306 } else {
308 if (!outbuf)
311 }
312
315
316 if (inbuf != outbuf)
318
320 }
321
323 {
325
328 }
329
331 {
335 },
336 { NULL }
337 };
338
340 {
344 },
345 { NULL }
346 };
347
357 .priv_class = &aphaser_class,
358 };