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
29
41
44 int nb_samples, int channels);
46
47 #define OFFSET(x) offsetof(AudioEchoContext, x)
48 #define A AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
49
55 { NULL }
56 };
57
59
61 {
62 char *p;
63
64 *nb_items = 1;
65 for (p = item_str; *p; p++) {
66 if (*p == '|')
67 (*nb_items)++;
68 }
69
70 }
71
72 static void fill_items(
char *item_str,
int *nb_items,
float *items)
73 {
74 char *p, *saveptr = NULL;
75 int i, new_nb_items = 0;
76
77 p = item_str;
78 for (i = 0; i < *nb_items; i++) {
80 p = NULL;
81 new_nb_items += sscanf(tstr, "%f", &items[i]) == 1;
82 }
83
84 *nb_items = new_nb_items;
85 }
86
88 {
90
94
98 }
99
101 {
103 int nb_delays, nb_decays, i;
104
108 }
109
112
117
120
121 if (nb_delays != nb_decays) {
122 av_log(ctx,
AV_LOG_ERROR,
"Number of delays %d differs from number of decays %d.\n", nb_delays, nb_decays);
124 }
125
130 }
131
135
136 for (i = 0; i < nb_delays; i++) {
137 if (s->
delay[i] <= 0 || s->
delay[i] > 90000) {
140 }
144 }
145 }
146
148
150 return 0;
151 }
152
154 {
161 };
162
164 if (!layouts)
167
169 if (!formats)
172
174 if (!formats)
177
178 return 0;
179 }
180
181 #define MOD(a, b) (((a) >= (b)) ? (a) - (b) : (a))
182
183 #define ECHO(name, type, min, max) \
184 static void echo_samples_## name ##p(AudioEchoContext *ctx, \
185 uint8_t **delayptrs, \
186 uint8_t * const *src, uint8_t **dst, \
187 int nb_samples, int channels) \
188 { \
189 const double out_gain = ctx->out_gain; \
190 const double in_gain = ctx->in_gain; \
191 const int nb_echoes = ctx->nb_echoes; \
192 const int max_samples = ctx->max_samples; \
193 int i, j, chan, av_uninit(index); \
194 \
195 av_assert1(channels > 0); /* would corrupt delay_index */ \
196 \
197 for (chan = 0; chan < channels; chan++) { \
198 const type *s = (type *)src[chan]; \
199 type *d = (type *)dst[chan]; \
200 type *dbuf = (type *)delayptrs[chan]; \
201 \
202 index = ctx->delay_index; \
203 for (i = 0; i < nb_samples; i++, s++, d++) { \
204 double out, in; \
205 \
206 in = *s; \
207 out = in * in_gain; \
208 for (j = 0; j < nb_echoes; j++) { \
209 int ix = index + max_samples - ctx->samples[j]; \
210 ix = MOD(ix, max_samples); \
211 out += dbuf[ix] * ctx->decay[j]; \
212 } \
213 out *= out_gain; \
214 \
215 *d = av_clipd(out, min, max); \
216 dbuf[index] = in; \
217 \
218 index = MOD(index + 1, max_samples); \
219 } \
220 } \
221 ctx->delay_index = index; \
222 }
223
224 ECHO(dbl,
double, -1.0, 1.0 )
225 ECHO(flt,
float, -1.0, 1.0 )
226 ECHO(s16, int16_t, INT16_MIN, INT16_MAX)
228
230 {
233 float volume = 1.0;
234 int i;
235
237 s->
samples[i] = s->
delay[i] * outlink->sample_rate / 1000.0;
239 volume += s->
decay[i];
240 }
241
245 }
247
250 "out_gain %f can cause saturation of output\n", s->
out_gain);
251
252 switch (outlink->format) {
257 }
258
259
263
265 outlink->channels,
267 outlink->format, 0);
268 }
269
271 {
275
278 } else {
280 if (!out_frame)
283 }
284
287
288 if (frame != out_frame)
290
293 }
294
296 {
300
302
306
308 if (!frame)
311
316
319
323
325 }
326
328 }
329
331 {
335 },
336 { NULL }
337 };
338
340 {
345 },
346 { NULL }
347 };
348
354 .priv_class = &aecho_class,
359 };