[FFmpeg-devel] [PATCH 2/2] lavfi: add sine audio source.

Stefano Sabatini stefasab at gmail.com
Tue Mar 19 01:17:01 CET 2013


On date Saturday 2013-03-16 16:44:06 +0100, Nicolas George encoded:
> 
> Signed-off-by: Nicolas George <nicolas.george at normalesup.org>
> ---
>  Changelog                |    1 +
>  doc/filters.texi         |   51 +++++++++++
>  libavfilter/Makefile     |    1 +
>  libavfilter/allfilters.c |    1 +
>  libavfilter/asrc_sine.c  |  228 ++++++++++++++++++++++++++++++++++++++++++++++
>  libavfilter/version.h    |    2 +-
>  6 files changed, 283 insertions(+), 1 deletion(-)
>  create mode 100644 libavfilter/asrc_sine.c
> 
> diff --git a/Changelog b/Changelog
> index 516b293..958634b 100644
> --- a/Changelog
> +++ b/Changelog
> @@ -8,6 +8,7 @@ version <next>:
>    or vice versa
>  - support for Monkey's Audio versions from 3.93
>  - perms and aperms filters
> +- sine audio filter source
>  
>  
>  version 1.2:
> diff --git a/doc/filters.texi b/doc/filters.texi
> index 0dbec8e..de16a2f 100644
> --- a/doc/filters.texi
> +++ b/doc/filters.texi
> @@ -1653,6 +1653,57 @@ ffplay -f lavfi flite=text='No more be grieved for which that thou hast done.'
>  For more information about libflite, check:
>  @url{http://www.speech.cs.cmu.edu/flite/}
>  
> + at section sine
> +
> +Generate an audio signal made of a sine wave with amplitude 1/8.
> +
> +The audio signal is bit-exact.
> +
> +It accepts a list of options in the form of @var{key}=@var{value} pairs
> +separated by ":". If the option name is omitted, the first option is the
> +frequency and the second option is the beep factor.
> +
> +The supported options are:
> +
> + at table @option
> +
> + at item frequency, f
> +Set the carrier frequency. Default is 440 Hz.
> +
> + at item beep_factor, b
> +Enable a periodic beep every second with frequency @var{beep_factor} times
> +the carrier frequency. Default is 0, meaning the beep is disabled.

A possibly useful option could be beep_duration.

[...]
> +static void make_sin_table(int16_t *sin)
> +{
> +    unsigned half_pi = 1 << (LOG_PERIOD - 2);
> +    unsigned ampls = AMPLITUDE << AMPLITUDE_SHIFT;
> +    uint64_t unit2 = (uint64_t)(ampls * ampls) << 32;
> +    unsigned step, i, c, s, k, new_k, n2;
> +
> +    /* Principle: if u = exp(i*a1) and v = exp(i*a2), then
> +       exp(i*(a1+a2)/2) = (u+v) / length(u+v) */
> +    sin[0] = 0;
> +    sin[half_pi] = ampls;
> +    for (step = half_pi; step > 1; step /= 2) {
> +        /* k = (1 << 16) * amplitude / length(u+v)
> +           In exact values, k is constant at a given step */
> +        k = 0x10000;
> +        for (i = 0; i < half_pi / 2; i += step) {
> +            s = sin[i] + sin[i + step];
> +            c = sin[half_pi - i] + sin[half_pi - i - step];
> +            n2 = s * s + c * c;
> +            /* Newton's method to solve n² * k² = unit² */
> +            while (1) {
> +                new_k = (k + unit2 / ((uint64_t)k * n2) + 1) >> 1;
> +                if (k == new_k)
> +                    break;
> +                k = new_k;
> +            }
> +            sin[i + step / 2] = (k * s + 0x7FFF) >> 16;
> +            sin[half_pi - i - step / 2] = (k * c + 0x8000) >> 16;
> +        }
> +    }
> +    /* Unshift amplitude */
> +    for (i = 0; i <= half_pi; i++)
> +        sin[i] = (sin[i] + (1 << (AMPLITUDE_SHIFT - 1))) >> AMPLITUDE_SHIFT;
> +    /* Use symmetries to fill the other three quarters */
> +    for (i = 0; i < half_pi; i++)
> +        sin[half_pi * 2 - i] = sin[i];
> +    for (i = 0; i < 2 * half_pi; i++)
> +        sin[i + 2 * half_pi] = -sin[i];
> +}

The hope is that I'll be able to work the math, which is unlikely due
to my lack of time, so feel free to commit if you see no comments from
me or someone else in the next few days, thanks.
-- 
FFmpeg = Frenzy Freak Mastering Problematic Enhanced Geisha


More information about the ffmpeg-devel mailing list