blob: 87c82900970ba40523ff1bab9520f141f4a315c5
1 | /* |
2 | * Copyright (c) 1998 Juergen Mueller And Sundry Contributors |
3 | * This source code is freely redistributable and may be used for |
4 | * any purpose. This copyright notice must be maintained. |
5 | * Juergen Mueller And Sundry Contributors are not responsible for |
6 | * the consequences of using this software. |
7 | * |
8 | * Copyright (c) 2015 Paul B Mahol |
9 | * |
10 | * This file is part of FFmpeg. |
11 | * |
12 | * FFmpeg is free software; you can redistribute it and/or |
13 | * modify it under the terms of the GNU Lesser General Public |
14 | * License as published by the Free Software Foundation; either |
15 | * version 2.1 of the License, or (at your option) any later version. |
16 | * |
17 | * FFmpeg is distributed in the hope that it will be useful, |
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
20 | * Lesser General Public License for more details. |
21 | * |
22 | * You should have received a copy of the GNU Lesser General Public |
23 | * License along with FFmpeg; if not, write to the Free Software |
24 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
25 | */ |
26 | |
27 | /** |
28 | * @file |
29 | * chorus audio filter |
30 | */ |
31 | |
32 | #include "libavutil/avstring.h" |
33 | #include "libavutil/opt.h" |
34 | #include "audio.h" |
35 | #include "avfilter.h" |
36 | #include "internal.h" |
37 | #include "generate_wave_table.h" |
38 | |
39 | typedef struct ChorusContext { |
40 | const AVClass *class; |
41 | float in_gain, out_gain; |
42 | char *delays_str; |
43 | char *decays_str; |
44 | char *speeds_str; |
45 | char *depths_str; |
46 | float *delays; |
47 | float *decays; |
48 | float *speeds; |
49 | float *depths; |
50 | uint8_t **chorusbuf; |
51 | int **phase; |
52 | int *length; |
53 | int32_t **lookup_table; |
54 | int *counter; |
55 | int num_chorus; |
56 | int max_samples; |
57 | int channels; |
58 | int modulation; |
59 | int fade_out; |
60 | int64_t next_pts; |
61 | } ChorusContext; |
62 | |
63 | #define OFFSET(x) offsetof(ChorusContext, x) |
64 | #define A AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM |
65 | |
66 | static const AVOption chorus_options[] = { |
67 | { "in_gain", "set input gain", OFFSET(in_gain), AV_OPT_TYPE_FLOAT, {.dbl=.4}, 0, 1, A }, |
68 | { "out_gain", "set output gain", OFFSET(out_gain), AV_OPT_TYPE_FLOAT, {.dbl=.4}, 0, 1, A }, |
69 | { "delays", "set delays", OFFSET(delays_str), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, A }, |
70 | { "decays", "set decays", OFFSET(decays_str), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, A }, |
71 | { "speeds", "set speeds", OFFSET(speeds_str), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, A }, |
72 | { "depths", "set depths", OFFSET(depths_str), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, A }, |
73 | { NULL } |
74 | }; |
75 | |
76 | AVFILTER_DEFINE_CLASS(chorus); |
77 | |
78 | static void count_items(char *item_str, int *nb_items) |
79 | { |
80 | char *p; |
81 | |
82 | *nb_items = 1; |
83 | for (p = item_str; *p; p++) { |
84 | if (*p == '|') |
85 | (*nb_items)++; |
86 | } |
87 | |
88 | } |
89 | |
90 | static void fill_items(char *item_str, int *nb_items, float *items) |
91 | { |
92 | char *p, *saveptr = NULL; |
93 | int i, new_nb_items = 0; |
94 | |
95 | p = item_str; |
96 | for (i = 0; i < *nb_items; i++) { |
97 | char *tstr = av_strtok(p, "|", &saveptr); |
98 | p = NULL; |
99 | if (tstr) |
100 | new_nb_items += sscanf(tstr, "%f", &items[new_nb_items]) == 1; |
101 | } |
102 | |
103 | *nb_items = new_nb_items; |
104 | } |
105 | |
106 | static av_cold int init(AVFilterContext *ctx) |
107 | { |
108 | ChorusContext *s = ctx->priv; |
109 | int nb_delays, nb_decays, nb_speeds, nb_depths; |
110 | |
111 | if (!s->delays_str || !s->decays_str || !s->speeds_str || !s->depths_str) { |
112 | av_log(ctx, AV_LOG_ERROR, "Both delays & decays & speeds & depths must be set.\n"); |
113 | return AVERROR(EINVAL); |
114 | } |
115 | |
116 | count_items(s->delays_str, &nb_delays); |
117 | count_items(s->decays_str, &nb_decays); |
118 | count_items(s->speeds_str, &nb_speeds); |
119 | count_items(s->depths_str, &nb_depths); |
120 | |
121 | s->delays = av_realloc_f(s->delays, nb_delays, sizeof(*s->delays)); |
122 | s->decays = av_realloc_f(s->decays, nb_decays, sizeof(*s->decays)); |
123 | s->speeds = av_realloc_f(s->speeds, nb_speeds, sizeof(*s->speeds)); |
124 | s->depths = av_realloc_f(s->depths, nb_depths, sizeof(*s->depths)); |
125 | |
126 | if (!s->delays || !s->decays || !s->speeds || !s->depths) |
127 | return AVERROR(ENOMEM); |
128 | |
129 | fill_items(s->delays_str, &nb_delays, s->delays); |
130 | fill_items(s->decays_str, &nb_decays, s->decays); |
131 | fill_items(s->speeds_str, &nb_speeds, s->speeds); |
132 | fill_items(s->depths_str, &nb_depths, s->depths); |
133 | |
134 | if (nb_delays != nb_decays && nb_delays != nb_speeds && nb_delays != nb_depths) { |
135 | av_log(ctx, AV_LOG_ERROR, "Number of delays & decays & speeds & depths given must be same.\n"); |
136 | return AVERROR(EINVAL); |
137 | } |
138 | |
139 | s->num_chorus = nb_delays; |
140 | |
141 | if (s->num_chorus < 1) { |
142 | av_log(ctx, AV_LOG_ERROR, "At least one delay & decay & speed & depth must be set.\n"); |
143 | return AVERROR(EINVAL); |
144 | } |
145 | |
146 | s->length = av_calloc(s->num_chorus, sizeof(*s->length)); |
147 | s->lookup_table = av_calloc(s->num_chorus, sizeof(*s->lookup_table)); |
148 | |
149 | if (!s->length || !s->lookup_table) |
150 | return AVERROR(ENOMEM); |
151 | |
152 | s->next_pts = AV_NOPTS_VALUE; |
153 | |
154 | return 0; |
155 | } |
156 | |
157 | static int query_formats(AVFilterContext *ctx) |
158 | { |
159 | AVFilterFormats *formats; |
160 | AVFilterChannelLayouts *layouts; |
161 | static const enum AVSampleFormat sample_fmts[] = { |
162 | AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE |
163 | }; |
164 | int ret; |
165 | |
166 | layouts = ff_all_channel_counts(); |
167 | if (!layouts) |
168 | return AVERROR(ENOMEM); |
169 | ret = ff_set_common_channel_layouts(ctx, layouts); |
170 | if (ret < 0) |
171 | return ret; |
172 | |
173 | formats = ff_make_format_list(sample_fmts); |
174 | if (!formats) |
175 | return AVERROR(ENOMEM); |
176 | ret = ff_set_common_formats(ctx, formats); |
177 | if (ret < 0) |
178 | return ret; |
179 | |
180 | formats = ff_all_samplerates(); |
181 | if (!formats) |
182 | return AVERROR(ENOMEM); |
183 | return ff_set_common_samplerates(ctx, formats); |
184 | } |
185 | |
186 | static int config_output(AVFilterLink *outlink) |
187 | { |
188 | AVFilterContext *ctx = outlink->src; |
189 | ChorusContext *s = ctx->priv; |
190 | float sum_in_volume = 1.0; |
191 | int n; |
192 | |
193 | s->channels = outlink->channels; |
194 | |
195 | for (n = 0; n < s->num_chorus; n++) { |
196 | int samples = (int) ((s->delays[n] + s->depths[n]) * outlink->sample_rate / 1000.0); |
197 | int depth_samples = (int) (s->depths[n] * outlink->sample_rate / 1000.0); |
198 | |
199 | s->length[n] = outlink->sample_rate / s->speeds[n]; |
200 | |
201 | s->lookup_table[n] = av_malloc(sizeof(int32_t) * s->length[n]); |
202 | if (!s->lookup_table[n]) |
203 | return AVERROR(ENOMEM); |
204 | |
205 | ff_generate_wave_table(WAVE_SIN, AV_SAMPLE_FMT_S32, s->lookup_table[n], |
206 | s->length[n], 0., depth_samples, 0); |
207 | s->max_samples = FFMAX(s->max_samples, samples); |
208 | } |
209 | |
210 | for (n = 0; n < s->num_chorus; n++) |
211 | sum_in_volume += s->decays[n]; |
212 | |
213 | if (s->in_gain * (sum_in_volume) > 1.0 / s->out_gain) |
214 | av_log(ctx, AV_LOG_WARNING, "output gain can cause saturation or clipping of output\n"); |
215 | |
216 | s->counter = av_calloc(outlink->channels, sizeof(*s->counter)); |
217 | if (!s->counter) |
218 | return AVERROR(ENOMEM); |
219 | |
220 | s->phase = av_calloc(outlink->channels, sizeof(*s->phase)); |
221 | if (!s->phase) |
222 | return AVERROR(ENOMEM); |
223 | |
224 | for (n = 0; n < outlink->channels; n++) { |
225 | s->phase[n] = av_calloc(s->num_chorus, sizeof(int)); |
226 | if (!s->phase[n]) |
227 | return AVERROR(ENOMEM); |
228 | } |
229 | |
230 | s->fade_out = s->max_samples; |
231 | |
232 | return av_samples_alloc_array_and_samples(&s->chorusbuf, NULL, |
233 | outlink->channels, |
234 | s->max_samples, |
235 | outlink->format, 0); |
236 | } |
237 | |
238 | #define MOD(a, b) (((a) >= (b)) ? (a) - (b) : (a)) |
239 | |
240 | static int filter_frame(AVFilterLink *inlink, AVFrame *frame) |
241 | { |
242 | AVFilterContext *ctx = inlink->dst; |
243 | ChorusContext *s = ctx->priv; |
244 | AVFrame *out_frame; |
245 | int c, i, n; |
246 | |
247 | if (av_frame_is_writable(frame)) { |
248 | out_frame = frame; |
249 | } else { |
250 | out_frame = ff_get_audio_buffer(inlink, frame->nb_samples); |
251 | if (!out_frame) { |
252 | av_frame_free(&frame); |
253 | return AVERROR(ENOMEM); |
254 | } |
255 | av_frame_copy_props(out_frame, frame); |
256 | } |
257 | |
258 | for (c = 0; c < inlink->channels; c++) { |
259 | const float *src = (const float *)frame->extended_data[c]; |
260 | float *dst = (float *)out_frame->extended_data[c]; |
261 | float *chorusbuf = (float *)s->chorusbuf[c]; |
262 | int *phase = s->phase[c]; |
263 | |
264 | for (i = 0; i < frame->nb_samples; i++) { |
265 | float out, in = src[i]; |
266 | |
267 | out = in * s->in_gain; |
268 | |
269 | for (n = 0; n < s->num_chorus; n++) { |
270 | out += chorusbuf[MOD(s->max_samples + s->counter[c] - |
271 | s->lookup_table[n][phase[n]], |
272 | s->max_samples)] * s->decays[n]; |
273 | phase[n] = MOD(phase[n] + 1, s->length[n]); |
274 | } |
275 | |
276 | out *= s->out_gain; |
277 | |
278 | dst[i] = out; |
279 | |
280 | chorusbuf[s->counter[c]] = in; |
281 | s->counter[c] = MOD(s->counter[c] + 1, s->max_samples); |
282 | } |
283 | } |
284 | |
285 | s->next_pts = frame->pts + av_rescale_q(frame->nb_samples, (AVRational){1, inlink->sample_rate}, inlink->time_base); |
286 | |
287 | if (frame != out_frame) |
288 | av_frame_free(&frame); |
289 | |
290 | return ff_filter_frame(ctx->outputs[0], out_frame); |
291 | } |
292 | |
293 | static int request_frame(AVFilterLink *outlink) |
294 | { |
295 | AVFilterContext *ctx = outlink->src; |
296 | ChorusContext *s = ctx->priv; |
297 | int ret; |
298 | |
299 | ret = ff_request_frame(ctx->inputs[0]); |
300 | |
301 | if (ret == AVERROR_EOF && !ctx->is_disabled && s->fade_out) { |
302 | int nb_samples = FFMIN(s->fade_out, 2048); |
303 | AVFrame *frame; |
304 | |
305 | frame = ff_get_audio_buffer(outlink, nb_samples); |
306 | if (!frame) |
307 | return AVERROR(ENOMEM); |
308 | s->fade_out -= nb_samples; |
309 | |
310 | av_samples_set_silence(frame->extended_data, 0, |
311 | frame->nb_samples, |
312 | outlink->channels, |
313 | frame->format); |
314 | |
315 | frame->pts = s->next_pts; |
316 | if (s->next_pts != AV_NOPTS_VALUE) |
317 | s->next_pts += av_rescale_q(nb_samples, (AVRational){1, outlink->sample_rate}, outlink->time_base); |
318 | |
319 | ret = filter_frame(ctx->inputs[0], frame); |
320 | } |
321 | |
322 | return ret; |
323 | } |
324 | |
325 | static av_cold void uninit(AVFilterContext *ctx) |
326 | { |
327 | ChorusContext *s = ctx->priv; |
328 | int n; |
329 | |
330 | av_freep(&s->delays); |
331 | av_freep(&s->decays); |
332 | av_freep(&s->speeds); |
333 | av_freep(&s->depths); |
334 | |
335 | if (s->chorusbuf) |
336 | av_freep(&s->chorusbuf[0]); |
337 | av_freep(&s->chorusbuf); |
338 | |
339 | if (s->phase) |
340 | for (n = 0; n < s->channels; n++) |
341 | av_freep(&s->phase[n]); |
342 | av_freep(&s->phase); |
343 | |
344 | av_freep(&s->counter); |
345 | av_freep(&s->length); |
346 | |
347 | if (s->lookup_table) |
348 | for (n = 0; n < s->num_chorus; n++) |
349 | av_freep(&s->lookup_table[n]); |
350 | av_freep(&s->lookup_table); |
351 | } |
352 | |
353 | static const AVFilterPad chorus_inputs[] = { |
354 | { |
355 | .name = "default", |
356 | .type = AVMEDIA_TYPE_AUDIO, |
357 | .filter_frame = filter_frame, |
358 | }, |
359 | { NULL } |
360 | }; |
361 | |
362 | static const AVFilterPad chorus_outputs[] = { |
363 | { |
364 | .name = "default", |
365 | .type = AVMEDIA_TYPE_AUDIO, |
366 | .request_frame = request_frame, |
367 | .config_props = config_output, |
368 | }, |
369 | { NULL } |
370 | }; |
371 | |
372 | AVFilter ff_af_chorus = { |
373 | .name = "chorus", |
374 | .description = NULL_IF_CONFIG_SMALL("Add a chorus effect to the audio."), |
375 | .query_formats = query_formats, |
376 | .priv_size = sizeof(ChorusContext), |
377 | .priv_class = &chorus_class, |
378 | .init = init, |
379 | .uninit = uninit, |
380 | .inputs = chorus_inputs, |
381 | .outputs = chorus_outputs, |
382 | }; |
383 |