diff mbox

[FFmpeg-devel] libavfilter/af_ambisonic.c Added File for Ambisonic Filter

Message ID CAMmhPECO8mKk0=psMmWiW05s7ZV3+v-NpHaiUK1-_xyWnWGveA@mail.gmail.com
State Superseded
Headers show

Commit Message

Sanchit Sinha March 10, 2017, 6:47 p.m. UTC
libavfilter/af_ambisonic.c | 139
+++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 139 insertions(+)
 create mode 100644 libavfilter/af_ambisonic.c

+    .query_formats  = query_formats,
+    .priv_size      = sizeof(AmbisonicContext),
+    .priv_class     = &ambisonic_class,
+    // .uninit         = uninit,
+    .inputs         = inputs,
+    .outputs        = outputs,
+};
\ No newline at end of file

Comments

Paul B Mahol March 10, 2017, 7:03 p.m. UTC | #1
On 3/10/17, Sanchit Sinha <sanchit15083@iiitd.ac.in> wrote:
> libavfilter/af_ambisonic.c | 139
> +++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 139 insertions(+)
>  create mode 100644 libavfilter/af_ambisonic.c
>

Incomplete patch.

> diff --git a/libavfilter/af_ambisonic.c b/libavfilter/af_ambisonic.c
> new file mode 100644
> index 0000000..98b0e44
> --- /dev/null
> +++ b/libavfilter/af_ambisonic.c
> @@ -0,0 +1,139 @@
> +/*
> + * This file is part of FFmpeg.
> + *
> + * FFmpeg is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * FFmpeg is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with FFmpeg; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
> 02110-1301 USA
> + */
> +
> +#include <stdio.h>
> +#include "libavutil/avstring.h"
> +#include "libavutil/channel_layout.h"
> +#include "libavutil/opt.h"
> +#include "audio.h"
> +#include "avfilter.h"
> +#include "formats.h"
> +
> +#define root8 2.828

One can use sqrt(8) just fine.

> +
> +typedef struct AmbisonicContext {
> +    const AVClass *class;
> +    /*Not needed, if any new variables are to be used, this struct can be
> populated*/
> +
> +} AmbisonicContext;
> +
> +#define OFFSET(x) offsetof(AmbisonicContext, x) //Future use(maybe)
> +
> +static const AVOption ambisonic_options[] = {  //square will be an option
> +{NULL}
> +};
> +
> +AVFILTER_DEFINE_CLASS(ambisonic);
> +static int query_formats(AVFilterContext *ctx)
> +{
> +    AVFilterFormats *formats = NULL;
> +    AVFilterChannelLayouts *layout = NULL;
> +    int ret;
> +        if ((ret = ff_add_format             (&formats, AV_SAMPLE_FMT_FLTP
>   )) < 0 ||
> +        (ret = ff_set_common_formats         (ctx     , formats
>  )) < 0 ||
> +        (ret = ff_add_channel_layout         (&layout ,
> AV_CH_LAYOUT_4POINT0)) < 0 ||
> +        (ret = ff_set_common_channel_layouts (ctx     , layout
> )) < 0)
> +        return ret;
> +    formats = ff_all_samplerates();
> +    return ff_set_common_samplerates(ctx, formats);
> +}
> +static int filter_frame(AVFilterLink *inlink, AVFrame *in)
> +{
> +    AVFilterContext *ctx = inlink->dst;
> +    AVFilterLink *outlink = ctx->outputs[0];
> +    /*If variables used, this has to be created*/
> +    // AmbisonicContext *s = ctx->priv;
> +    // const float *src = (const float *)in->data[0];
> +    // float *dst;
> +    float *lf,*lb,*rb,*rf;
> +    AVFrame *out;
> +    int itr;
> +    float *w,*x,*y;
> +
> +    if (av_frame_is_writable(in)) {
> +        out = in;
> +    } else {
> +        out = ff_get_audio_buffer(inlink, in->nb_samples);
> +        if (!out) {
> +            av_frame_free(&in);
> +            return AVERROR(ENOMEM);
> +        }
> +        av_frame_copy_props(out, in);
> +    }
> +
> +    /*If planar samples are used, output must be put in dst*/
> +    //dst = (float *)out->data[0];
> +
> +    lf = (float *)malloc(sizeof(float));
> +    lb = (float *)malloc(sizeof(float));
> +    rb = (float *)malloc(sizeof(float));
> +    rf = (float *)malloc(sizeof(float));
> +

Why? This is unacceptable. Use normal float variables.

> +    for(itr=0;itr<in->nb_samples;itr++)
> +    {
> +        *lf=0,*lb=0,*rb=0,*rf=0;
> +        /*Float pointers to the samples*/
> +        w=(float *)(*(in->extended_data)+itr);
> +        x=(float *)(*(in->extended_data+1)+itr);
> +        y=(float *)(*(in->extended_data+2)+itr);

This can be simplified and moved above loop.
Good understanding of pointers is mandatory.

> +
> +        *lf = root8 * (2*(*w)+*x+*y);
> +        *lb = root8 * (2*(*w)-*x+*y);
> +        *rb = root8 * (2*(*w)-*x-*y);
> +        *rf = root8 * (2*(*w)+*x-*y);
> +
> +        /*Mathematical coefficients taken from :
> https://en.wikipedia.org/wiki/Ambisonics*/

Remove this comment.

> +        out->extended_data[0][itr]= *lf;
> +        out->extended_data[1][itr]= *lb;
> +        out->extended_data[2][itr]= *rb;
> +        out->extended_data[3][itr]= *rf;
> +    }
> +
> +    if (out != in)
> +        av_frame_free(&in);
> +    return ff_filter_frame(outlink, out);
> +}
> +
> +static const AVFilterPad inputs[] = {
> +    {
> +        .name         = "default",
> +        .type         = AVMEDIA_TYPE_AUDIO,
> +        .filter_frame = filter_frame,
> +        // .config_props = config_input,
> +    },
> +    { NULL }
> +};
> +
> +static const AVFilterPad outputs[] = {
> +    {
> +        .name = "default",
> +        .type = AVMEDIA_TYPE_AUDIO,
> +    },
> +    { NULL }
> +};
> +
> +AVFilter ff_af_ambisonic = {
> +    .name           = "ambisonic",
> +    .description    = NULL_IF_CONFIG_SMALL("An ambisonic filter"),
> +    .query_formats  = query_formats,
> +    .priv_size      = sizeof(AmbisonicContext),
> +    .priv_class     = &ambisonic_class,
> +    // .uninit         = uninit,
> +    .inputs         = inputs,
> +    .outputs        = outputs,
> +};
> \ No newline at end of file

Plese fix your editor or use something else less broken.
I hope you are not using MS notepad or MS Word.
Andy Furniss March 11, 2017, 10:11 a.m. UTC | #2
Sanchit Sinha wrote:
> libavfilter/af_ambisonic.c | 139

> +        w=(float *)(*(in->extended_data)+itr);
> +        x=(float *)(*(in->extended_data+1)+itr);
> +        y=(float *)(*(in->extended_data+2)+itr);
> +
> +        *lf = root8 * (2*(*w)+*x+*y);
> +        *lb = root8 * (2*(*w)-*x+*y);
> +        *rb = root8 * (2*(*w)-*x-*y);
> +        *rf = root8 * (2*(*w)+*x-*y);

Seems a bit misleading to call something ambisonic if all it will
do is 2d, so partial b-format to (square?) 4 channel.

Why not be more specific in the name so the limitation is clear.
Paul B Mahol March 11, 2017, 10:22 a.m. UTC | #3
On 3/11/17, Andy Furniss <adf.lists@gmail.com> wrote:
> Sanchit Sinha wrote:
>> libavfilter/af_ambisonic.c | 139
>
>> +        w=(float *)(*(in->extended_data)+itr);
>> +        x=(float *)(*(in->extended_data+1)+itr);
>> +        y=(float *)(*(in->extended_data+2)+itr);
>> +
>> +        *lf = root8 * (2*(*w)+*x+*y);
>> +        *lb = root8 * (2*(*w)-*x+*y);
>> +        *rb = root8 * (2*(*w)-*x-*y);
>> +        *rf = root8 * (2*(*w)+*x-*y);
>
> Seems a bit misleading to call something ambisonic if all it will
> do is 2d, so partial b-format to (square?) 4 channel.
>
> Why not be more specific in the name so the limitation is clear.

This is just for qualification task. Later filter willl be extended.

It will not be applied as is in tree.
Andy Furniss March 11, 2017, 10:53 a.m. UTC | #4
Paul B Mahol wrote:
> On 3/11/17, Andy Furniss <adf.lists@gmail.com> wrote:
>> Sanchit Sinha wrote:
>>> libavfilter/af_ambisonic.c | 139
>>
>>> +        w=(float *)(*(in->extended_data)+itr);
>>> +        x=(float *)(*(in->extended_data+1)+itr);
>>> +        y=(float *)(*(in->extended_data+2)+itr);
>>> +
>>> +        *lf = root8 * (2*(*w)+*x+*y);
>>> +        *lb = root8 * (2*(*w)-*x+*y);
>>> +        *rb = root8 * (2*(*w)-*x-*y);
>>> +        *rf = root8 * (2*(*w)+*x-*y);
>>
>> Seems a bit misleading to call something ambisonic if all it will
>> do is 2d, so partial b-format to (square?) 4 channel.
>>
>> Why not be more specific in the name so the limitation is clear.
>
> This is just for qualification task. Later filter willl be extended.
>
> It will not be applied as is in tree.

Ahh, OK.

A complicated subject.

Sanchit, in case you don't know, some of the people who were around at
the birth of ambisonics, plus ambdec author can be found on the list -

https://mail.music.vt.edu/mailman/listinfo/sursound
Sanchit Sinha March 11, 2017, 10:59 a.m. UTC | #5
Thanks Andy for the valuable info! It would be good to talk and learn from
these guys, especially for an amateur like me. :)

On Sat, Mar 11, 2017 at 4:23 PM, Andy Furniss <adf.lists@gmail.com> wrote:

> Paul B Mahol wrote:
>
>> On 3/11/17, Andy Furniss <adf.lists@gmail.com> wrote:
>>
>>> Sanchit Sinha wrote:
>>>
>>>> libavfilter/af_ambisonic.c | 139
>>>>
>>>
>>> +        w=(float *)(*(in->extended_data)+itr);
>>>> +        x=(float *)(*(in->extended_data+1)+itr);
>>>> +        y=(float *)(*(in->extended_data+2)+itr);
>>>> +
>>>> +        *lf = root8 * (2*(*w)+*x+*y);
>>>> +        *lb = root8 * (2*(*w)-*x+*y);
>>>> +        *rb = root8 * (2*(*w)-*x-*y);
>>>> +        *rf = root8 * (2*(*w)+*x-*y);
>>>>
>>>
>>> Seems a bit misleading to call something ambisonic if all it will
>>> do is 2d, so partial b-format to (square?) 4 channel.
>>>
>>> Why not be more specific in the name so the limitation is clear.
>>>
>>
>> This is just for qualification task. Later filter willl be extended.
>>
>> It will not be applied as is in tree.
>>
>
> Ahh, OK.
>
> A complicated subject.
>
> Sanchit, in case you don't know, some of the people who were around at
> the birth of ambisonics, plus ambdec author can be found on the list -
>
> https://mail.music.vt.edu/mailman/listinfo/sursound
>
>
>
>
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
diff mbox

Patch

diff --git a/libavfilter/af_ambisonic.c b/libavfilter/af_ambisonic.c
new file mode 100644
index 0000000..98b0e44
--- /dev/null
+++ b/libavfilter/af_ambisonic.c
@@ -0,0 +1,139 @@ 
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
+ */
+
+#include <stdio.h>
+#include "libavutil/avstring.h"
+#include "libavutil/channel_layout.h"
+#include "libavutil/opt.h"
+#include "audio.h"
+#include "avfilter.h"
+#include "formats.h"
+
+#define root8 2.828
+
+typedef struct AmbisonicContext {
+    const AVClass *class;
+    /*Not needed, if any new variables are to be used, this struct can be
populated*/
+
+} AmbisonicContext;
+
+#define OFFSET(x) offsetof(AmbisonicContext, x) //Future use(maybe)
+
+static const AVOption ambisonic_options[] = {  //square will be an option
+{NULL}
+};
+
+AVFILTER_DEFINE_CLASS(ambisonic);
+static int query_formats(AVFilterContext *ctx)
+{
+    AVFilterFormats *formats = NULL;
+    AVFilterChannelLayouts *layout = NULL;
+    int ret;
+        if ((ret = ff_add_format             (&formats, AV_SAMPLE_FMT_FLTP
  )) < 0 ||
+        (ret = ff_set_common_formats         (ctx     , formats
 )) < 0 ||
+        (ret = ff_add_channel_layout         (&layout ,
AV_CH_LAYOUT_4POINT0)) < 0 ||
+        (ret = ff_set_common_channel_layouts (ctx     , layout
)) < 0)
+        return ret;
+    formats = ff_all_samplerates();
+    return ff_set_common_samplerates(ctx, formats);
+}
+static int filter_frame(AVFilterLink *inlink, AVFrame *in)
+{
+    AVFilterContext *ctx = inlink->dst;
+    AVFilterLink *outlink = ctx->outputs[0];
+    /*If variables used, this has to be created*/
+    // AmbisonicContext *s = ctx->priv;
+    // const float *src = (const float *)in->data[0];
+    // float *dst;
+    float *lf,*lb,*rb,*rf;
+    AVFrame *out;
+    int itr;
+    float *w,*x,*y;
+
+    if (av_frame_is_writable(in)) {
+        out = in;
+    } else {
+        out = ff_get_audio_buffer(inlink, in->nb_samples);
+        if (!out) {
+            av_frame_free(&in);
+            return AVERROR(ENOMEM);
+        }
+        av_frame_copy_props(out, in);
+    }
+
+    /*If planar samples are used, output must be put in dst*/
+    //dst = (float *)out->data[0];
+
+    lf = (float *)malloc(sizeof(float));
+    lb = (float *)malloc(sizeof(float));
+    rb = (float *)malloc(sizeof(float));
+    rf = (float *)malloc(sizeof(float));
+
+    for(itr=0;itr<in->nb_samples;itr++)
+    {
+        *lf=0,*lb=0,*rb=0,*rf=0;
+        /*Float pointers to the samples*/
+        w=(float *)(*(in->extended_data)+itr);
+        x=(float *)(*(in->extended_data+1)+itr);
+        y=(float *)(*(in->extended_data+2)+itr);
+
+        *lf = root8 * (2*(*w)+*x+*y);
+        *lb = root8 * (2*(*w)-*x+*y);
+        *rb = root8 * (2*(*w)-*x-*y);
+        *rf = root8 * (2*(*w)+*x-*y);
+
+        /*Mathematical coefficients taken from :
https://en.wikipedia.org/wiki/Ambisonics*/
+        out->extended_data[0][itr]= *lf;
+        out->extended_data[1][itr]= *lb;
+        out->extended_data[2][itr]= *rb;
+        out->extended_data[3][itr]= *rf;
+    }
+
+    if (out != in)
+        av_frame_free(&in);
+    return ff_filter_frame(outlink, out);
+}
+
+static const AVFilterPad inputs[] = {
+    {
+        .name         = "default",
+        .type         = AVMEDIA_TYPE_AUDIO,
+        .filter_frame = filter_frame,
+        // .config_props = config_input,
+    },
+    { NULL }
+};
+
+static const AVFilterPad outputs[] = {
+    {
+        .name = "default",
+        .type = AVMEDIA_TYPE_AUDIO,
+    },
+    { NULL }
+};
+
+AVFilter ff_af_ambisonic = {
+    .name           = "ambisonic",
+    .description    = NULL_IF_CONFIG_SMALL("An ambisonic filter"),