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

#define WITH_QUEUE TRUE

static void event_loop(GstElement *pipe)
{
    GstBus *bus;
    GstMessage *message = NULL;
    
    bus = gst_element_get_bus(GST_ELEMENT(pipe));
    
    while(TRUE) {
        message = gst_bus_poll(bus, GST_MESSAGE_ANY, -1);
        
        g_assert(message != NULL);
        
        switch(message->type) {
        case GST_MESSAGE_EOS:
            gst_message_unref(message);
            return;
        case GST_MESSAGE_WARNING:
        case GST_MESSAGE_ERROR: {
            GError *gerror;
            gchar *debug;
            
            gst_message_parse_error(message, &gerror, &debug);
            gst_object_default_error(GST_MESSAGE_SRC(message), gerror, debug);
            gst_message_unref(message);
            g_error_free(gerror);
            g_free(debug);
            return;
        }
        default:
            gst_message_unref(message);
            break;
        }
    }
}

int main(int argc, char *argv[])
{
    gst_init(&argc, &argv);
    
    GstElement *pipeline, *src, *tee, *queue1, *queue2, *id1, *id2, *adder, *sink;
    
    pipeline = gst_pipeline_new("pipeline");
    src = gst_element_factory_make("audiotestsrc", "src");
    tee = gst_element_factory_make("tee", "tee");
    if (WITH_QUEUE) {
        queue1 = gst_element_factory_make("queue", "queue1");
        queue2 = gst_element_factory_make("queue", "queue2");
    }
    id1 = gst_element_factory_make("identity", "id1");
    id2 = gst_element_factory_make("identity", "id2");
    adder = gst_element_factory_make("adder", "adder");
    sink = gst_element_factory_make("alsasink", "sink");
    
    /* add elements */
    if (WITH_QUEUE) {
        gst_bin_add_many(GST_BIN(pipeline), src, tee, queue1, queue2, id1, id2, adder, sink, NULL);
    } else {
        gst_bin_add_many(GST_BIN(pipeline), src, tee, id1, id2, adder, sink, NULL);
    }
    
    /* link elements */
    gst_element_link(src, tee);
    if (WITH_QUEUE) {
        gst_element_link_many(tee, queue1, id1, adder, NULL);
        gst_element_link_many(tee, queue2, id2, adder, NULL);
    } else {
        gst_element_link_many(tee, id1, adder, NULL);
        gst_element_link_many(tee, id2, adder, NULL);
    }
    gst_element_link(adder, sink);
    
    /* start pipeline */
    gst_element_set_state(pipeline, GST_STATE_PLAYING);
    event_loop(pipeline);
    
    exit(0);
}
