c++cgstreamerdigital-filter

Gstreamer audiofirfilter


I'm trying to use the element audiofirfilter in a gstreamer pipeline. For now without luck.

I searched the docs and the mailinglist for examples, but there is only one that, unfortunately, I can't compile due to some missing pieces (I'm on an embedded system).

My pipeline is

if (data.pipeline == NULL) {
        data.pipeline = gst_pipeline_new ("pipeline");
        data.fakesrc    = gst_element_factory_make("fakesrc", NULL);
        data.capsfilter = gst_element_factory_make("capsfilter", NULL);
        data.audioconvert   = gst_element_factory_make("audioconvert", NULL);
        data.audiofirfilter = gst_element_factory_make("audiofirfilter", NULL);
        data.alsasink   = gst_element_factory_make("alsasink", NULL);

        gst_bin_add_many (GST_BIN (data.pipeline), data.fakesrc, data.capsfilter, data.audioconvert, data.audiofirfilter, data.alsasink, NULL);

        if (!gst_element_link_many (data.fakesrc, data.capsfilter, data.audioconvert, data.audiofirfilter, data.alsasink, NULL) ) {
            qDebug() << "Error: not all elements could be linked!";
            return;
        }

        GstCaps* caps = gst_caps_new_simple("audio/x-raw",
                                                                                "format", G_TYPE_STRING, "S16LE",
                                                                                "rate", G_TYPE_INT, SAMPLING_FREQUENCY,
                                                                                "channels", G_TYPE_INT,2,
                                                                                "layout", G_TYPE_STRING, "interleaved",
                                                                                NULL);


        g_object_set(G_OBJECT(data.capsfilter), "caps", caps, NULL);


        g_object_set (G_OBJECT (data.fakesrc),
                                    "sync", TRUE,
                                    "signal-handoffs", TRUE,
                                    "sizemax",BUFFER_SIZE,
                                    "sizetype",2,NULL);

        gdouble filter_kernel[16] = {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

        GValueArray *va;
        va = g_value_array_new (1);

        GValue v = { 0, };
        g_value_init (&v, G_TYPE_DOUBLE);

        for (int i = 0; i < 16; i++) {
            g_value_set_double (&v, filter_kernel[i]);
            g_value_array_append (va, &v);
            g_value_reset (&v);
        }
        g_object_set (G_OBJECT (data.audiofirfilter), "kernel", va, NULL);
        g_object_set (G_OBJECT (data.audiofirfilter), "latency", (gint64) (16 / 2), NULL);

        g_value_array_free (va);


        g_signal_connect (data.fakesrc, "handoff", G_CALLBACK (SourceHandoffCallback), /*&data*/ this);

        GstBus *bus;
        bus = gst_pipeline_get_bus (GST_PIPELINE(data.pipeline));
        gst_object_unref (bus);
    }

I only want to implement an unitary impulse response for now. The pipeline won't play at all. It is a stereo pipeline.

Does anyone has a working example of an application of audiofirfilter that doesn't involve fft? the inverse-fft?

Thanks


Solution

  • I tried a simpler pipeline, and this works:

    gst_init (NULL,NULL);
    
    cFusionDrumsPlayerData data;
    
    data.pipeline = gst_pipeline_new ("pipeline");
    data.src    = gst_element_factory_make("audiotestsrc", NULL);
    data.audiofirfilter = gst_element_factory_make("audiofirfilter", NULL);
    data.sink   = gst_element_factory_make("autoaudiosink", NULL);
    
    gst_bin_add_many (GST_BIN (data.pipeline), data.src, data.audiofirfilter, data.sink, NULL);
    
    if (!gst_element_link_many (data.src, data.audiofirfilter, data.sink, NULL) ) {
        return;
    }
    
    
    gdouble filter_kernel[16] = {0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
    
    GValueArray *va;
    va = g_value_array_new (1);
    
    GValue v = { 0, };
    g_value_init (&v, G_TYPE_DOUBLE);
    
    for (int i = 0; i < 16; i++) {
        g_value_set_double (&v, filter_kernel[i]);
        g_value_array_append (va, &v);
        g_value_reset (&v);
    }
    g_object_set (G_OBJECT (data.audiofirfilter), "kernel", va, NULL);
    g_object_set (G_OBJECT (data.audiofirfilter), "latency", (gint64) (16 / 2), NULL);
    
    g_value_array_free (va);
    
    gst_element_set_state (data.pipeline, GST_STATE_PLAYING);
    

    I think that the problem can be the source (fakesrc)