Browse code

avfilter: add chorus filter

Signed-off-by: Paul B Mahol <onemda@gmail.com>

Paul B Mahol authored on 2014/06/24 17:35:37
Showing 6 changed files
... ...
@@ -16,6 +16,7 @@ version <next>:
16 16
 - unpack DivX-style packed B-frames in MPEG-4 bitstream filter
17 17
 - WebM Live Chunk Muxer
18 18
 - nvenc level and tier options
19
+- chorus filter
19 20
 
20 21
 
21 22
 version 2.6:
... ...
@@ -1320,6 +1320,61 @@ front_center.wav -map '[LFE]' lfe.wav -map '[SL]' side_left.wav -map '[SR]'
1320 1320
 side_right.wav
1321 1321
 @end example
1322 1322
 
1323
+@section chorus
1324
+Add a chorus effect to the audio.
1325
+
1326
+Can make a single vocal sound like a chorus, but can also be applied to instrumentation.
1327
+
1328
+Chorus resembles an echo effect with a short delay, but whereas with echo the delay is
1329
+constant, with chorus, it is varied using using sinusoidal or triangular modulation.
1330
+The modulation depth defines the range the modulated delay is played before or after
1331
+the delay. Hence the delayed sound will sound slower or faster, that is the delayed
1332
+sound tuned around the original one, like in a chorus where some vocals are slightly
1333
+off key.
1334
+
1335
+It accepts the following parameters:
1336
+@table @option
1337
+@item in_gain
1338
+Set input gain. Default is 0.4.
1339
+
1340
+@item out_gain
1341
+Set output gain. Default is 0.4.
1342
+
1343
+@item delays
1344
+Set delays. A typical delay is around 40ms to 60ms.
1345
+
1346
+@item decays
1347
+Set decays.
1348
+
1349
+@item speeds
1350
+Set speeds.
1351
+
1352
+@item depths
1353
+Set depths.
1354
+@end table
1355
+
1356
+@subsection Examples
1357
+
1358
+@itemize
1359
+@item
1360
+A single delay:
1361
+@example
1362
+chorus=0.7:0.9:55:0.4:0.25:2
1363
+@end example
1364
+
1365
+@item
1366
+Two delays:
1367
+@example
1368
+chorus=0.6:0.9:50|60:0.4|0.32:0.25|0.4:2|1.3
1369
+@end example
1370
+
1371
+@item
1372
+Fuller sounding chorus with three delays:
1373
+@example
1374
+chorus=0.5:0.9:50|60|40:0.4|0.32|0.3:0.25|0.4|0.3:2|2.3|1.3
1375
+@end example
1376
+@end itemize
1377
+
1323 1378
 @section compand
1324 1379
 Compress or expand the audio's dynamic range.
1325 1380
 
... ...
@@ -64,6 +64,7 @@ OBJS-$(CONFIG_BIQUAD_FILTER)                 += af_biquads.o
64 64
 OBJS-$(CONFIG_BS2B_FILTER)                   += af_bs2b.o
65 65
 OBJS-$(CONFIG_CHANNELMAP_FILTER)             += af_channelmap.o
66 66
 OBJS-$(CONFIG_CHANNELSPLIT_FILTER)           += af_channelsplit.o
67
+OBJS-$(CONFIG_CHORUS_FILTER)                 += af_chorus.o generate_wave_table.o
67 68
 OBJS-$(CONFIG_COMPAND_FILTER)                += af_compand.o
68 69
 OBJS-$(CONFIG_DCSHIFT_FILTER)                += af_dcshift.o
69 70
 OBJS-$(CONFIG_EARWAX_FILTER)                 += af_earwax.o
70 71
new file mode 100644
... ...
@@ -0,0 +1,379 @@
0
+/*
1
+ * Copyright (c) 1998 Juergen Mueller And Sundry Contributors
2
+ * This source code is freely redistributable and may be used for
3
+ * any purpose.  This copyright notice must be maintained.
4
+ * Juergen Mueller And Sundry Contributors are not responsible for
5
+ * the consequences of using this software.
6
+ *
7
+ * Copyright (c) 2015 Paul B Mahol
8
+ *
9
+ * This file is part of FFmpeg.
10
+ *
11
+ * FFmpeg is free software; you can redistribute it and/or
12
+ * modify it under the terms of the GNU Lesser General Public
13
+ * License as published by the Free Software Foundation; either
14
+ * version 2.1 of the License, or (at your option) any later version.
15
+ *
16
+ * FFmpeg is distributed in the hope that it will be useful,
17
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19
+ * Lesser General Public License for more details.
20
+ *
21
+ * You should have received a copy of the GNU Lesser General Public
22
+ * License along with FFmpeg; if not, write to the Free Software
23
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24
+ */
25
+
26
+/**
27
+ * @file
28
+ * chorus audio filter
29
+ */
30
+
31
+#include "libavutil/avstring.h"
32
+#include "libavutil/opt.h"
33
+#include "audio.h"
34
+#include "avfilter.h"
35
+#include "internal.h"
36
+#include "generate_wave_table.h"
37
+
38
+typedef struct ChorusContext {
39
+    const AVClass *class;
40
+    float in_gain, out_gain;
41
+    char *delays_str;
42
+    char *decays_str;
43
+    char *speeds_str;
44
+    char *depths_str;
45
+    float *delays;
46
+    float *decays;
47
+    float *speeds;
48
+    float *depths;
49
+    uint8_t **chorusbuf;
50
+    int **phase;
51
+    int *length;
52
+    int32_t **lookup_table;
53
+    int *counter;
54
+    int num_chorus;
55
+    int max_samples;
56
+    int channels;
57
+    int modulation;
58
+    int fade_out;
59
+    int64_t next_pts;
60
+} ChorusContext;
61
+
62
+#define OFFSET(x) offsetof(ChorusContext, x)
63
+#define A AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
64
+
65
+static const AVOption chorus_options[] = {
66
+    { "in_gain",  "set input gain",  OFFSET(in_gain),    AV_OPT_TYPE_FLOAT,  {.dbl=.4}, 0, 1, A },
67
+    { "out_gain", "set output gain", OFFSET(out_gain),   AV_OPT_TYPE_FLOAT,  {.dbl=.4}, 0, 1, A },
68
+    { "delays",   "set delays",      OFFSET(delays_str), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, A },
69
+    { "decays",   "set decays",      OFFSET(decays_str), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, A },
70
+    { "speeds",   "set speeds",      OFFSET(speeds_str), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, A },
71
+    { "depths",   "set depths",      OFFSET(depths_str), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, A },
72
+    { NULL }
73
+};
74
+
75
+AVFILTER_DEFINE_CLASS(chorus);
76
+
77
+static void count_items(char *item_str, int *nb_items)
78
+{
79
+    char *p;
80
+
81
+    *nb_items = 1;
82
+    for (p = item_str; *p; p++) {
83
+        if (*p == '|')
84
+            (*nb_items)++;
85
+    }
86
+
87
+}
88
+
89
+static void fill_items(char *item_str, int *nb_items, float *items)
90
+{
91
+    char *p, *saveptr = NULL;
92
+    int i, new_nb_items = 0;
93
+
94
+    p = item_str;
95
+    for (i = 0; i < *nb_items; i++) {
96
+        char *tstr = av_strtok(p, "|", &saveptr);
97
+        p = NULL;
98
+        new_nb_items += sscanf(tstr, "%f", &items[i]) == 1;
99
+    }
100
+
101
+    *nb_items = new_nb_items;
102
+}
103
+
104
+static av_cold int init(AVFilterContext *ctx)
105
+{
106
+    ChorusContext *s = ctx->priv;
107
+    int nb_delays, nb_decays, nb_speeds, nb_depths;
108
+
109
+    if (!s->delays_str || !s->decays_str || !s->speeds_str || !s->depths_str) {
110
+        av_log(ctx, AV_LOG_ERROR, "Both delays & decays & speeds & depths must be set.\n");
111
+        return AVERROR(EINVAL);
112
+    }
113
+
114
+    count_items(s->delays_str, &nb_delays);
115
+    count_items(s->decays_str, &nb_decays);
116
+    count_items(s->speeds_str, &nb_speeds);
117
+    count_items(s->depths_str, &nb_depths);
118
+
119
+    s->delays = av_realloc_f(s->delays, nb_delays, sizeof(*s->delays));
120
+    s->decays = av_realloc_f(s->decays, nb_decays, sizeof(*s->decays));
121
+    s->speeds = av_realloc_f(s->speeds, nb_speeds, sizeof(*s->speeds));
122
+    s->depths = av_realloc_f(s->depths, nb_depths, sizeof(*s->depths));
123
+
124
+    if (!s->delays || !s->decays || !s->speeds || !s->depths)
125
+        return AVERROR(ENOMEM);
126
+
127
+    fill_items(s->delays_str, &nb_delays, s->delays);
128
+    fill_items(s->decays_str, &nb_decays, s->decays);
129
+    fill_items(s->speeds_str, &nb_speeds, s->speeds);
130
+    fill_items(s->depths_str, &nb_depths, s->depths);
131
+
132
+    if (nb_delays != nb_decays && nb_delays != nb_speeds && nb_delays != nb_depths) {
133
+        av_log(ctx, AV_LOG_ERROR, "Number of delays & decays & speeds & depths given must be same.\n");
134
+        return AVERROR(EINVAL);
135
+    }
136
+
137
+    s->num_chorus = nb_delays;
138
+
139
+    if (s->num_chorus < 1) {
140
+        av_log(ctx, AV_LOG_ERROR, "At least one delay & decay & speed & depth must be set.\n");
141
+        return AVERROR(EINVAL);
142
+    }
143
+
144
+    s->length = av_calloc(s->num_chorus, sizeof(*s->length));
145
+    s->lookup_table = av_calloc(s->num_chorus, sizeof(*s->lookup_table));
146
+
147
+    if (!s->length || !s->lookup_table)
148
+        return AVERROR(ENOMEM);
149
+
150
+    s->next_pts = AV_NOPTS_VALUE;
151
+
152
+    return 0;
153
+}
154
+
155
+static int query_formats(AVFilterContext *ctx)
156
+{
157
+    AVFilterFormats *formats;
158
+    AVFilterChannelLayouts *layouts;
159
+    static const enum AVSampleFormat sample_fmts[] = {
160
+        AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE
161
+    };
162
+    int ret;
163
+
164
+    layouts = ff_all_channel_layouts();
165
+    if (!layouts)
166
+        return AVERROR(ENOMEM);
167
+    ret = ff_set_common_channel_layouts(ctx, layouts);
168
+    if (ret < 0)
169
+        return ret;
170
+
171
+    formats = ff_make_format_list(sample_fmts);
172
+    if (!formats)
173
+        return AVERROR(ENOMEM);
174
+    ret = ff_set_common_formats(ctx, formats);
175
+    if (ret < 0)
176
+        return ret;
177
+
178
+    formats = ff_all_samplerates();
179
+    if (!formats)
180
+        return AVERROR(ENOMEM);
181
+    return ff_set_common_samplerates(ctx, formats);
182
+}
183
+
184
+static int config_output(AVFilterLink *outlink)
185
+{
186
+    AVFilterContext *ctx = outlink->src;
187
+    ChorusContext *s = ctx->priv;
188
+    float sum_in_volume = 1.0;
189
+    int n;
190
+
191
+    s->channels = outlink->channels;
192
+
193
+    for (n = 0; n < s->num_chorus; n++) {
194
+        int samples = (int) ((s->delays[n] + s->depths[n]) * outlink->sample_rate / 1000.0);
195
+        int depth_samples = (int) (s->depths[n] * outlink->sample_rate / 1000.0);
196
+
197
+        s->length[n] = outlink->sample_rate / s->speeds[n];
198
+
199
+        s->lookup_table[n] = av_malloc(sizeof(int32_t) * s->length[n]);
200
+        if (!s->lookup_table[n])
201
+            return AVERROR(ENOMEM);
202
+
203
+        ff_generate_wave_table(WAVE_SIN, AV_SAMPLE_FMT_S32, s->lookup_table[n],
204
+                               s->length[n], 0., depth_samples, 0);
205
+        s->max_samples = FFMAX(s->max_samples, samples);
206
+    }
207
+
208
+    for (n = 0; n < s->num_chorus; n++)
209
+        sum_in_volume += s->decays[n];
210
+
211
+    if (s->in_gain * (sum_in_volume) > 1.0 / s->out_gain)
212
+        av_log(ctx, AV_LOG_WARNING, "output gain can cause saturation or clipping of output\n");
213
+
214
+    s->counter = av_calloc(outlink->channels, sizeof(*s->counter));
215
+    if (!s->counter)
216
+        return AVERROR(ENOMEM);
217
+
218
+    s->phase = av_calloc(outlink->channels, sizeof(*s->phase));
219
+    if (!s->phase)
220
+        return AVERROR(ENOMEM);
221
+
222
+    for (n = 0; n < outlink->channels; n++) {
223
+        s->phase[n] = av_calloc(s->num_chorus, sizeof(int));
224
+        if (!s->phase[n])
225
+            return AVERROR(ENOMEM);
226
+    }
227
+
228
+    s->fade_out = s->max_samples;
229
+
230
+    return av_samples_alloc_array_and_samples(&s->chorusbuf, NULL,
231
+                                              outlink->channels,
232
+                                              s->max_samples,
233
+                                              outlink->format, 0);
234
+}
235
+
236
+#define MOD(a, b) (((a) >= (b)) ? (a) - (b) : (a))
237
+
238
+static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
239
+{
240
+    AVFilterContext *ctx = inlink->dst;
241
+    ChorusContext *s = ctx->priv;
242
+    AVFrame *out_frame;
243
+    int c, i, n;
244
+
245
+    if (av_frame_is_writable(frame)) {
246
+        out_frame = frame;
247
+    } else {
248
+        out_frame = ff_get_audio_buffer(inlink, frame->nb_samples);
249
+        if (!out_frame)
250
+            return AVERROR(ENOMEM);
251
+        av_frame_copy_props(out_frame, frame);
252
+    }
253
+
254
+    for (c = 0; c < inlink->channels; c++) {
255
+        const float *src = (const float *)frame->extended_data[c];
256
+        float *dst = (float *)out_frame->extended_data[c];
257
+        float *chorusbuf = (float *)s->chorusbuf[c];
258
+        int *phase = s->phase[c];
259
+
260
+        for (i = 0; i < frame->nb_samples; i++) {
261
+            float out, in = src[i];
262
+
263
+            out = in * s->in_gain;
264
+
265
+            for (n = 0; n < s->num_chorus; n++) {
266
+                out += chorusbuf[MOD(s->max_samples + s->counter[c] -
267
+                                     s->lookup_table[n][phase[n]],
268
+                                     s->max_samples)] * s->decays[n];
269
+                phase[n] = MOD(phase[n] + 1, s->length[n]);
270
+            }
271
+
272
+            out *= s->out_gain;
273
+
274
+            dst[i] = out;
275
+
276
+            chorusbuf[s->counter[c]] = in;
277
+            s->counter[c] = MOD(s->counter[c] + 1, s->max_samples);
278
+        }
279
+    }
280
+
281
+    s->next_pts = frame->pts + av_rescale_q(frame->nb_samples, (AVRational){1, inlink->sample_rate}, inlink->time_base);
282
+
283
+    if (frame != out_frame)
284
+        av_frame_free(&frame);
285
+
286
+    return ff_filter_frame(ctx->outputs[0], out_frame);
287
+}
288
+
289
+static int request_frame(AVFilterLink *outlink)
290
+{
291
+    AVFilterContext *ctx = outlink->src;
292
+    ChorusContext *s = ctx->priv;
293
+    int ret;
294
+
295
+    ret = ff_request_frame(ctx->inputs[0]);
296
+
297
+    if (ret == AVERROR_EOF && !ctx->is_disabled && s->fade_out) {
298
+        int nb_samples = FFMIN(s->fade_out, 2048);
299
+        AVFrame *frame;
300
+
301
+        frame = ff_get_audio_buffer(outlink, nb_samples);
302
+        if (!frame)
303
+            return AVERROR(ENOMEM);
304
+        s->fade_out -= nb_samples;
305
+
306
+        av_samples_set_silence(frame->extended_data, 0,
307
+                               frame->nb_samples,
308
+                               outlink->channels,
309
+                               frame->format);
310
+
311
+        frame->pts = s->next_pts;
312
+        if (s->next_pts != AV_NOPTS_VALUE)
313
+            s->next_pts += av_rescale_q(nb_samples, (AVRational){1, outlink->sample_rate}, outlink->time_base);
314
+
315
+        ret = filter_frame(ctx->inputs[0], frame);
316
+    }
317
+
318
+    return ret;
319
+}
320
+
321
+static av_cold void uninit(AVFilterContext *ctx)
322
+{
323
+    ChorusContext *s = ctx->priv;
324
+    int n;
325
+
326
+    av_freep(&s->delays);
327
+    av_freep(&s->decays);
328
+    av_freep(&s->speeds);
329
+    av_freep(&s->depths);
330
+
331
+    if (s->chorusbuf)
332
+        av_freep(&s->chorusbuf[0]);
333
+    av_freep(&s->chorusbuf);
334
+
335
+    if (s->phase)
336
+        for (n = 0; n < s->channels; n++)
337
+            av_freep(&s->phase[n]);
338
+    av_freep(&s->phase);
339
+
340
+    av_freep(&s->counter);
341
+    av_freep(&s->length);
342
+
343
+    if (s->lookup_table)
344
+        for (n = 0; n < s->num_chorus; n++)
345
+            av_freep(&s->lookup_table[n]);
346
+    av_freep(&s->lookup_table);
347
+}
348
+
349
+static const AVFilterPad chorus_inputs[] = {
350
+    {
351
+        .name         = "default",
352
+        .type         = AVMEDIA_TYPE_AUDIO,
353
+        .filter_frame = filter_frame,
354
+    },
355
+    { NULL }
356
+};
357
+
358
+static const AVFilterPad chorus_outputs[] = {
359
+    {
360
+        .name          = "default",
361
+        .type          = AVMEDIA_TYPE_AUDIO,
362
+        .request_frame = request_frame,
363
+        .config_props  = config_output,
364
+    },
365
+    { NULL }
366
+};
367
+
368
+AVFilter ff_af_chorus = {
369
+    .name          = "chorus",
370
+    .description   = NULL_IF_CONFIG_SMALL("Add a chorus effect to the audio."),
371
+    .query_formats = query_formats,
372
+    .priv_size     = sizeof(ChorusContext),
373
+    .priv_class    = &chorus_class,
374
+    .init          = init,
375
+    .uninit        = uninit,
376
+    .inputs        = chorus_inputs,
377
+    .outputs       = chorus_outputs,
378
+};
... ...
@@ -80,6 +80,7 @@ void avfilter_register_all(void)
80 80
     REGISTER_FILTER(BS2B,           bs2b,           af);
81 81
     REGISTER_FILTER(CHANNELMAP,     channelmap,     af);
82 82
     REGISTER_FILTER(CHANNELSPLIT,   channelsplit,   af);
83
+    REGISTER_FILTER(CHORUS,         chorus,         af);
83 84
     REGISTER_FILTER(COMPAND,        compand,        af);
84 85
     REGISTER_FILTER(DCSHIFT,        dcshift,        af);
85 86
     REGISTER_FILTER(EARWAX,         earwax,         af);
... ...
@@ -30,8 +30,8 @@
30 30
 #include "libavutil/version.h"
31 31
 
32 32
 #define LIBAVFILTER_VERSION_MAJOR  5
33
-#define LIBAVFILTER_VERSION_MINOR  13
34
-#define LIBAVFILTER_VERSION_MICRO 101
33
+#define LIBAVFILTER_VERSION_MINOR  14
34
+#define LIBAVFILTER_VERSION_MICRO 100
35 35
 
36 36
 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
37 37
                                                LIBAVFILTER_VERSION_MINOR, \