Multi channel Pipeline

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Multi channel Pipeline

diegoavila
Hi, Im new at using gstreamer (advanced topics), I want to create a
multichannel pipeline and  i want to control the volume of each channel ,
I've been loking for information and couldnt find anything useful , also im
using windows (I found an example that used alsasrc and other used
jackaudiosink but is not viable for my OS)
Thanks in advance!!



--
Sent from: http://gstreamer-devel.966125.n4.nabble.com/
_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

Re: Multi channel Pipeline

Nicolas Dufresne-5


Le mar. 1 oct. 2019 22 h 10, diegoavila <[hidden email]> a écrit :
Hi, Im new at using gstreamer (advanced topics), I want to create a
multichannel pipeline and  i want to control the volume of each channel ,
I've been loking for information and couldnt find anything useful , also im
using windows (I found an example that used alsasrc and other used
jackaudiosink but is not viable for my OS)
Thanks in advance!!

I think wasapi plugin is what uses the most recent Windows sound API. Pretty much all audio sources plugins works the same, so examples should still be relevant. As per dealing with multiple channel in GStreamer, what is most often done is to split each channel into its own branch of the graph, using deinterleave element. And then reassemble using audiointerleave.




--
Sent from: http://gstreamer-devel.966125.n4.nabble.com/
_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel

_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

Re: Multi channel Pipeline

diegoavila
Actually i switched to debian and it worked, but i dont know how can i add
another channel to this pipeline im stuck
this is my pipeline:
gst-launch-1.0 -v filesrc location=/home/arion/Downloads/test2.mp3 name=src
! decodebin ! deinterleave keep-positions=true name=d interleave name=i !
autoaudiosink d.src_0 ! queue ! volume volume=1 ! i.sink_1 d.src_1 ! queue !
volume volume=0 ! i.sink_2

i wanna add 2 more channels



--
Sent from: http://gstreamer-devel.966125.n4.nabble.com/
_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

Re: Multi channel Pipeline

Nicolas Dufresne-5


Le mer. 2 oct. 2019 22 h 10, diegoavila <[hidden email]> a écrit :
Actually i switched to debian and it worked, but i dont know how can i add
another channel to this pipeline im stuck
this is my pipeline:
gst-launch-1.0 -v filesrc location=/home/arion/Downloads/test2.mp3 name=src
! decodebin ! deinterleave keep-positions=true name=d interleave name=i !
autoaudiosink d.src_0 ! queue ! volume volume=1 ! i.sink_1 d.src_1 ! queue !
volume volume=0 ! i.sink_2

i wanna add 2 more channels

Just a note, I'm not totally certain I understood the goal. deinterleave will expose as many SRC pads as there is channels on it's sink pad. If you want to interleave channels from other sources, you'll need to do some programming (C, RUST, Python, etc. there is plenty of choices) to set the channel position mask to let audiointerleave know in which order to place them.





--
Sent from: http://gstreamer-devel.966125.n4.nabble.com/
_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel

_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

Re: Multi channel Pipeline

diegoavila
Hello Nicolas this is my actual code :
#include <gst/gst.h>
#include <gst/app/gstappsrc.h>

#include <stdio.h>
#include <string.h>
#include <stdlib.h>


#include <gdk-pixbuf/gdk-pixbuf.h>
#define CHUNK_SIZE  4096
typedef struct {
    GstPipeline *pipeline;
    GstAppSrc *src;
    GstElement *sink;
    GstElement *decoder;
    GstElement *audio_convert;
    GstElement *audiosink;
    GstElement *deinterleave;
    GstElement *resample;
    GMainLoop *loop;
    guint sourceid;
    GMappedFile *file;
    guint8 *data;
    gsize length;
    guint64 offset;
}gst_app_t;

static gst_app_t gst_app;

#define BUFF_SIZE (1024)
static gboolean print_field (GQuark field, const GValue * value, gpointer
pfx) {

  gchar *str = gst_value_serialize (value);

  g_print ("%s  %15s: %s\n", (gchar *) pfx, g_quark_to_string (field), str);

  g_free (str);

  return TRUE;

}
static void print_caps (const GstCaps * caps, const gchar * pfx) {

  guint i;

  g_return_if_fail (caps != NULL);

  if (gst_caps_is_any (caps)) {

    g_print ("%sANY\n", pfx);

    return;

  }

  if (gst_caps_is_empty (caps)) {

    g_print ("%sEMPTY\n", pfx);

    return;

  }

  for (i = 0; i < gst_caps_get_size (caps); i++) {

    GstStructure *structure = gst_caps_get_structure (caps, i);

    g_print ("%s%s\n", pfx, gst_structure_get_name (structure));

    gst_structure_foreach (structure, print_field, (gpointer) pfx);

  }

}

static void print_pad_capabilities (GstElement *element, gchar *pad_name) {

  GstPad *pad = NULL;

  GstCaps *caps = NULL;

  /* Retrieve pad */

  pad = gst_element_get_static_pad (element, pad_name);

  if (!pad) {

    g_printerr ("Could not retrieve pad '%s'\n", pad_name);

    return;

  }

  /* Retrieve negotiated caps (or acceptable caps if negotiation is not
finished yet) */

  caps = gst_pad_get_current_caps (pad);

  if (!caps)

    caps = gst_pad_query_caps (pad, NULL);

  /* Print and free */

  g_print ("Caps for the %s pad:\n", pad_name);

  print_caps (caps, "      ");

  gst_caps_unref (caps);

  gst_object_unref (pad);

}
static gboolean read_data(gst_app_t *app)
{
    GstBuffer *buffer;
    guint len;
    GstFlowReturn ret;

    if (app->offset >= app->length) {
        /* we are EOS, send end-of-stream and remove the source */
        g_signal_emit_by_name (app->src, "end-of-stream", &ret);
        return FALSE;
    }

    /* read the next chunk */
    buffer = gst_buffer_new ();

    len = CHUNK_SIZE;
    if (app->offset + len > app->length)
        len = app->length - app->offset;

    gst_buffer_append_memory (buffer,
                              gst_memory_new_wrapped
(GST_MEMORY_FLAG_READONLY,
                                                      app->data,
app->length, app->offset, len, NULL, NULL));

    g_print ("feed buffer %p, offset %" G_GUINT64_FORMAT "-%u \n", buffer,
             app->offset, len);
    g_signal_emit_by_name (app->src, "push-buffer", buffer, &ret);
    gst_buffer_unref (buffer);
    if (ret != GST_FLOW_OK) {
        /* some error, stop sending data */
        return FALSE;
    }

    app->offset += len;

    return TRUE;
}

static void start_feed (GstElement * playbin, guint size, gst_app_t * app)
{
    if (app->sourceid == 0) {
        g_print("Start feeding \n");
        app->sourceid = g_idle_add ((GSourceFunc) read_data, app);
    }
}

static void stop_feed (GstElement * playbin, gst_app_t * app)
{
    if (app->sourceid != 0) {
        g_print ("Stop feeding \n");
        g_source_remove (app->sourceid);
        app->sourceid = 0;
    }
}
static void cb_new_pad (GstElement *element, GstPad *pad, gpointer data)
{
  gchar *name;
  GstElement *other = data;

  name = gst_pad_get_name (pad);
  g_print ("A new pad %s was created for %s\n", name,
gst_element_get_name(element));
  g_free (name);

  g_print ("element %s will be linked to %s\n",
           gst_element_get_name(element),
           gst_element_get_name(other));
  gst_element_link(element, other);
}

static gboolean bus_callback(GstBus *bus, GstMessage *message, gpointer
*ptr)
{
    gst_app_t *app = (gst_app_t*)ptr;

    switch(GST_MESSAGE_TYPE(message)){

    case GST_MESSAGE_ERROR:{
        gchar *debug;
        GError *err;

        gst_message_parse_error(message, &err, &debug);
        g_print("Error %s\n", err->message);
        g_error_free(err);
        g_free(debug);
        g_main_loop_quit(app->loop);
    }
    break;

    case GST_MESSAGE_EOS:
        g_print("End of stream\n");
        g_main_loop_quit(app->loop);
        break;

    default:
        g_print("got message %s\n", \
            gst_message_type_get_name (GST_MESSAGE_TYPE (message)));
        break;
    }

    return TRUE;
}

int _channels=0;

void il_new_pad (GstElement *decodebin, GstPad *pad, gst_app_t * data)

{
   GstElement* element=0;

 //  std::cout<<_channels;

        if (data->pipeline)

        {

                GstElement *queue, *aconv, *ares, *appsink;

                queue = gst_element_factory_make("queue",  NULL);

                aconv = gst_element_factory_make("audioconvert", NULL);

                appsink = gst_element_factory_make("alsasink", NULL);

               

                gst_bin_add_many (GST_BIN (data->pipeline), queue, aconv,
appsink, NULL);

                 gst_element_link(queue, aconv);

                 gst_element_link(aconv,appsink);

       

                g_object_set(G_OBJECT (appsink), "sync", FALSE, NULL);

               

                element=queue;

                gst_element_sync_state_with_parent(element);

                ++_channels;

        }

        GstCaps *caps;

        GstStructure *str;

        GstPad *audiopad;

        /* only link once */

        audiopad = gst_element_get_static_pad (element, "sink");

        if (GST_PAD_IS_LINKED (audiopad))

        {

                g_object_unref (audiopad);

        }

        /* check media type */

        caps = gst_pad_query_caps (pad,NULL);

        print_caps(caps, "  ");

        str = gst_caps_get_structure (caps, 0);

        if (!g_strrstr (gst_structure_get_name (str), "audio"))

        {

                //std::cerr<<"won't connect!"<<std::endl;

                gst_caps_unref (caps);

                gst_object_unref (audiopad);

        }

        gst_caps_unref (caps);

        /* link'n'play */

        gst_pad_link (pad, audiopad);    

}




int main(int argc, char *argv[])
{
    gst_app_t *app = &amp;gst_app;
    GstBus *bus;
    GError *error = NULL;
    GstStateChangeReturn state_ret;
    GstPad *tee_audio_pad, *tee_video_pad, *tee_app_pad;
    GstPad *queue_audio_pad, *queue_video_pad, *queue_app_pad;

  /* try to open the file as an mmapped file */
    app->file = g_mapped_file_new ("/home/arion/Downloads/test2.mp3", FALSE,
&error);
    if (error) {
        g_print ("failed to open file: %s \n", error->message);
        g_error_free (error);
    }
    /* get some vitals, this will be used to read data from the mmapped file
and
    * feed it to appsrc. */
    app->length = g_mapped_file_get_length (app->file);
    app->data = (guint8 *) g_mapped_file_get_contents (app->file);
    app->offset = 0;
   

    gst_init(NULL, NULL);

    app->pipeline = (GstPipeline*)gst_pipeline_new("mypipeline");
    bus = gst_pipeline_get_bus(app->pipeline);
    gst_bus_add_watch(bus, (GstBusFunc)bus_callback, app);
    gst_object_unref(bus);

    app->src = (GstAppSrc*)gst_element_factory_make("appsrc", "mysrc");
    app->decoder = gst_element_factory_make("decodebin", "src");
    app->audio_convert = gst_element_factory_make("audioconvert",
"myaudio_convert");
    app->audiosink = gst_element_factory_make("alsasink", "d");
    app->deinterleave = gst_element_factory_make("deinterleave", NULL);

    g_assert(app->src);
    g_assert(app->decoder);
    g_assert(app->audio_convert);
    g_assert(app->audiosink);
    g_assert(app->deinterleave);

    g_object_set (app->src, "size", (gint64) app->length, NULL);
    g_signal_connect(app->src, "need-data", G_CALLBACK(start_feed), app);
    g_signal_connect(app->src, "enough-data", G_CALLBACK(stop_feed), app);
    g_signal_connect(app->decoder, "pad-added", G_CALLBACK(cb_new_pad),
app->audio_convert);
    g_signal_connect (app->deinterleave, "pad-added", G_CALLBACK
(il_new_pad), app);
   // GstCaps *bufcaps=gst_caps_from_string (" audio/x-raw,
format=(string)S16LE, layout=(string)interleaved, rate=(int)44100,
channels=(int)6, channel-mask=(bitmask)0x000000000000003f");
   // g_object_set(G_OBJECT(app->src), "caps", bufcaps, NULL);

    gst_bin_add_many(GST_BIN(app->pipeline), (GstElement*)app->src,
app->decoder, app->audio_convert, app->audiosink,app->deinterleave,  NULL);
   

    if(!gst_element_link((GstElement*)app->src, app->decoder)){
        g_warning("failed to link src anbd decoder");
    }
    if(!gst_element_link(app->audio_convert, app->deinterleave)){
        g_warning("failed to link audio_convert and deinterleave");
    }
    if(!gst_element_link(app->audio_convert, app->audiosink)){
        g_warning("failed to link audio_convert and audiosink");
    }

    state_ret = gst_element_set_state((GstElement*)app->pipeline,
GST_STATE_PLAYING);
    g_warning("set state returned %d\n", state_ret);

    app->loop = g_main_loop_new(NULL, FALSE);
    printf("Running main loop\n");
    g_main_loop_run(app->loop);

    state_ret = gst_element_set_state((GstElement*)app->pipeline,
GST_STATE_NULL);
    g_warning("set state null returned %d\n", state_ret);

    return 0;
}
My main problem is that i cant convert the mp3 to 6 channel , could you help
me please



--
Sent from: http://gstreamer-devel.966125.n4.nabble.com/
_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel