This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Linux: simple gstreamer alsasrc alsasink example program.



Tool/software: Linux

Hi,

I'm writing the gstreamer program for my custom board on sitara processor.There is some problem and I decided to check it on simple example.

So I wrote mini program to stream audio from alsasrc to alsasink, but there is no errors and nothing in speakers.

Here is the code:

#include <gst/gst.h>
#include <glib.h>

static gboolean
bus_call (GstBus     *bus,
          GstMessage *msg,
          gpointer    data){
  GMainLoop *loop = (GMainLoop *) data;

  switch (GST_MESSAGE_TYPE (msg)) {

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

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

      gst_message_parse_error (msg, &error, &debug);
      g_free (debug);

      g_printerr ("Error: %s\n", error->message);
      g_error_free (error);

      g_main_loop_quit (loop);
      break;
    }
    default:
      break;
  }

  return TRUE;
}

/* Main function for audio pipeline initialization and looping streaming process  */
gint
main (gint argc, gchar **argv) {
	GMainLoop *loop;
	GstElement *pipeline, *audio_source, *sink;	
	GstBus *bus;
	guint bus_watch_id;
	GstCaps *caps;
	gboolean ret;

	/* Initialization of gstreamer */
    gst_init (&argc, &argv);
    loop = g_main_loop_new (NULL, FALSE);

    /* Elements creation */
    pipeline 	 = gst_pipeline_new ("audio_stream");
    audio_source = gst_element_factory_make ("alsasrc", "audio_source");
  	sink 		 = gst_element_factory_make ("alsasink", "audio_sink");

	if (!pipeline) {
		g_printerr ("Audio: Pipeline couldn't be created\n");
		return -1;
	}
	if (!audio_source) {
		g_printerr ("Audio: alsasrc couldn't be created\n");
		return -1;
	}
	if (!sink) {
		g_printerr ("Audio: Output file couldn't be created\n");
		return -1;
	}

	g_object_set (G_OBJECT (audio_source), "device", "hw:0,0", NULL);
	g_object_set (G_OBJECT (sink), "device", "hw:0,0", NULL);

	bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
	bus_watch_id = gst_bus_add_watch (bus, bus_call, loop);
	gst_object_unref (bus);

	gst_bin_add_many (GST_BIN(pipeline), audio_source, sink, NULL);

  	caps = gst_caps_new_simple ("audio/x-raw", "format", G_TYPE_STRING, "S16LE",  "layout", G_TYPE_STRING, "interleaved", "rate", G_TYPE_INT, (int)44100, "channels", G_TYPE_INT, (int)2, NULL);
  	ret = gst_element_link_filtered (audio_source, sink, caps);
  	if (!ret) {
		g_print ("audio_source and sink couldn't be linked\n");
		gst_caps_unref (caps);
		return FALSE;
	}

	gst_element_set_state (pipeline, GST_STATE_PLAYING);

	g_print ("streaming...\n");
	g_main_loop_run (loop);

	g_print ("Returned, stopping stream\n");
	gst_element_set_state (pipeline, GST_STATE_NULL);

	g_print ("Deleting pipeline\n");
	gst_object_unref (GST_OBJECT (pipeline));
	g_source_remove (bus_watch_id);
	g_main_loop_unref (loop);

	return 0;
}


Did I use every necessary elements?


Kr,

Alexander.

  • Hello,

    Did you verify that the pipeline is working on the device?

    BR
    Margarita
  • yeap, this pipeline works fine:
    gst-launch-1.0 alsasrc num-buffers=500 device="hw:0,0" ! alsasink sync=false

    Maybe I should set volume value?

    Kr,
    Alexander
  • Hello,

    If this pipeline is working, it shall work in the application also.
    I would recommend you when you execute the app to add ./...... --gst-debug=3 -v

    I tried to integrate your pipeline in app: alsasrc device="hw:0,0" ! capsfilter ! queue ! alsasink

    Check the below source code:

    #include <glib.h>
    #include <stdio.h>
    #include <string.h>
    #include <string>
    #include <pthread.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <signal.h>
    #include <fcntl.h>
    #include <sys/mman.h>
    #include <sys/ioctl.h>
    #include <string>

    #include <gst/gst.h>


    static gboolean link_alsa_element_with_filter (GstElement *element1, GstElement *element2)

    {
    /* CAPS to be linked:
    * audio/x-raw-int, signed=true, width=32, depth=32, format=S32LE, rate=96000, channels=4
    * */

    gboolean link_ok;
    GstCaps *caps;

    caps = gst_caps_new_simple ("audio/x-raw-int",
    "endianness", G_TYPE_INT, 1234,
    "signed", G_TYPE_BOOLEAN, TRUE,
    "width", G_TYPE_INT, 16,
    "depth", G_TYPE_INT, 16,
    "channels", G_TYPE_INT, 2,
    "rate", G_TYPE_INT, 44100,

    NULL);

    link_ok = gst_element_link_filtered (element1, element2, caps);
    gst_caps_unref (caps);

    if (!link_ok) {
    g_warning ("Failed to link element1 and element2!(source->queue)");
    }
    return link_ok;
    }


    static gboolean bus_call (GstBus *bus, GstMessage *msg, gpointer data)
    {
    GMainLoop *loop = (GMainLoop *) data;

    switch (GST_MESSAGE_TYPE (msg)) {
    case GST_MESSAGE_EOS:
    g_print ("End of stream\n");
    g_main_loop_quit (loop);
    break;

    case GST_MESSAGE_ERROR: {
    gchar *debug;
    GError *error;
    gst_message_parse_error (msg, &error, &debug);
    g_free (debug);
    g_printerr ("Error: %s\n", error->message);
    g_error_free (error);
    g_main_loop_quit (loop);
    break;
    }
    default:
    break;
    }

    return TRUE;
    }


    /* Main function for audio pipeline initialization and looping streaming process */

    gint main (gint argc, gchar **argv) {

    GMainLoop *loop;

    GstElement *pipeline;
    GstElement *source;
    GstElement *queues;
    GstElement *sink;

    GstBus *bus;

    // guint bus_watch_id;

    GstCaps *caps;

    // gboolean ret;


    /* Initialisation */
    gst_init (&argc, &argv);
    loop = g_main_loop_new (NULL, FALSE);

    /* Create gstreamer elements:
    */

    pipeline = gst_pipeline_new ("audio_stream");

    source = gst_element_factory_make ("alsasrc", "audio_source");
    g_return_val_if_fail (source, -1);
    g_object_set (G_OBJECT (source), "device", "plughw:0,0", NULL);

    queues = gst_element_factory_make ("queue", "queues");
    g_return_val_if_fail (queues, -1);

    sink = gst_element_factory_make ("alsasink", "audio_sink");
    g_return_val_if_fail (sink, -1);
    //g_object_set (G_OBJECT (sink), "device", "plughw:0,0", NULL);




    /* Add a message handler */
    bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
    gst_bus_add_watch (bus, bus_call, loop);
    gst_object_unref (bus);

    /* Add elements to the bin before linking them. */
    gst_bin_add (GST_BIN (pipeline), source);
    gst_bin_add (GST_BIN (pipeline), queues);
    gst_bin_add (GST_BIN (pipeline), sink);



    /* Link the pipeline */


    link_alsa_element_with_filter (source, queues);
    gst_element_link_pads (queues, "src", sink, "sink");




    /* Set the pipeline to "playing" state */
    g_print ("Playing: %s\n", argv[1]);
    gst_element_set_state (pipeline, GST_STATE_PLAYING);

    /* Iterate */

    g_print ("Running...\n");


    g_main_loop_run (loop);

    /* Out of the main loop, clean up nicely */
    g_print ("Returned, stopping playback\n");
    gst_element_set_state (pipeline, GST_STATE_NULL);


    g_print ("Deleting pipeline\n");
    gst_object_unref (GST_OBJECT (pipeline));

    return 0;
    }


    I have not tried the above code.


    Hope this helps as reference.

    BR
    Margarita
  • I notice that your pipeline
    alsasrc device="hw:0,0" ! capsfilter ! queue ! alsasink
    doesn't work without sync=false parameter.

    So I added
    g_object_set (G_OBJECT (sink), "sync", FALSE, NULL);
    and code begin successfuly work.

    Thank you!

    Kr,
    Alexander
  • Hello,

    I am glad that the issue is solved.
    Please verify this thread.

    BR
    Margarita
  • Hello,

    I am sorry I saw that I have missed one more line in my code :

    gst_message_unref( msg );

    Could you add it in here:

    case GST_MESSAGE_ERROR: {

    gchar *debug;

    GError *error;

    gst_message_parse_error (msg, &error, &debug);

    g_free (debug);

    g_printerr ("Error: %s\n", error->message);

    g_error_free (error);

    g_main_loop_quit (loop);

    break;

    }

    default:

    break;

    }

    gst_message_unref( msg );

    return TRUE;

    }

    BR
    Margarita