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
28
40
43 int nb_samples, int channels);
45
46 #define OFFSET(x) offsetof(AudioEchoContext, x)
47 #define A AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
48
55 };
56
58
60 {
61 char *p;
62
63 *nb_items = 1;
64 for (p = item_str; *p; p++) {
65 if (*p == '|')
66 (*nb_items)++;
67 }
68
69 }
70
71 static void fill_items(
char *item_str,
int *nb_items,
float *items)
72 {
73 char *p, *saveptr =
NULL;
74 int i, new_nb_items = 0;
75
76 p = item_str;
77 for (i = 0; i < *nb_items; i++) {
80 new_nb_items += sscanf(tstr, "%f", &items[i]) == 1;
81 }
82
83 *nb_items = new_nb_items;
84 }
85
87 {
89
93
97 }
98
100 {
102 int nb_delays, nb_decays, i;
103
107 }
108
111
116
119
120 if (nb_delays != nb_decays) {
121 av_log(ctx,
AV_LOG_ERROR,
"Number of delays %d differs from number of decays %d.\n", nb_delays, nb_decays);
123 }
124
129 }
130
134
135 for (i = 0; i < nb_delays; i++) {
136 if (s->
delay[i] <= 0 || s->
delay[i] > 90000) {
139 }
143 }
144 }
145
147
149 return 0;
150 }
151
153 {
160 };
161
163 if (!layouts)
166
168 if (!formats)
171
173 if (!formats)
176
177 return 0;
178 }
179
180 #define MOD(a, b) (((a) >= (b)) ? (a) - (b) : (a))
181
182 #define ECHO(name, type, min, max) \
183 static void echo_samples_## name ##p(AudioEchoContext *ctx, \
184 uint8_t **delayptrs, \
185 uint8_t * const *src, uint8_t **dst, \
186 int nb_samples, int channels) \
187 { \
188 const double out_gain = ctx->out_gain; \
189 const double in_gain = ctx->in_gain; \
190 const int nb_echoes = ctx->nb_echoes; \
191 const int max_samples = ctx->max_samples; \
192 int i, j, chan, av_uninit(index); \
193 \
194 av_assert1(channels > 0); /* would corrupt delay_index */ \
195 \
196 for (chan = 0; chan < channels; chan++) { \
197 const type *s = (type *)src[chan]; \
198 type *d = (type *)dst[chan]; \
199 type *dbuf = (type *)delayptrs[chan]; \
200 \
201 index = ctx->delay_index; \
202 for (i = 0; i < nb_samples; i++, s++, d++) { \
203 double out, in; \
204 \
205 in = *s; \
206 out = in * in_gain; \
207 for (j = 0; j < nb_echoes; j++) { \
208 int ix = index + max_samples - ctx->samples[j]; \
209 ix = MOD(ix, max_samples); \
210 out += dbuf[ix] * ctx->decay[j]; \
211 } \
212 out *= out_gain; \
213 \
214 *d = av_clipd(out, min, max); \
215 dbuf[index] = in; \
216 \
217 index = MOD(index + 1, max_samples); \
218 } \
219 } \
220 ctx->delay_index = index; \
221 }
222
223 ECHO(dbl,
double, -1.0, 1.0 )
224 ECHO(flt,
float, -1.0, 1.0 )
225 ECHO(s16, int16_t, INT16_MIN, INT16_MAX)
227
229 {
232 float volume = 1.0;
233 int i;
234
236 s->
samples[i] = s->
delay[i] * outlink->sample_rate / 1000.0;
238 volume += s->
decay[i];
239 }
240
244 }
246
249 "out_gain %f can cause saturation of output\n", s->
out_gain);
250
251 switch (outlink->format) {
256 }
257
258
262
264 outlink->channels,
266 outlink->format, 0);
267 }
268
270 {
274
277 } else {
279 if (!out_frame)
282 }
283
286
288
289 if (
frame != out_frame)
291
293 }
294
296 {
300
302
306
308 if (!frame)
311
316
319
323
325 }
326
328 }
329
331 {
335 },
337 };
338
340 {
345 },
347 };
348
354 .priv_class = &aecho_class,
359 };