GMainLoop *loop;
snd_seq_t *seq;
+ int queue;
int port_count;
snd_seq_addr_t *seq_ports;
snd_midi_event_t *parser;
goto error;
}
+ /*
+ * Prevent Valgrind from reporting cached configuration as memory leaks, see:
+ * http://git.alsa-project.org/?p=alsa-lib.git;a=blob;f=MEMORY-LEAK;hb=HEAD
+ */
+ snd_config_update_free_global();
+
ret = snd_seq_set_client_name (app->seq, DEFAULT_CLIENT_NAME);
if (ret < 0) {
GST_ERROR ("Cannot set client name - %s", snd_strerror (ret));
}
static int
+start_queue_timer (snd_seq_t *seq, int queue)
+{
+ int ret;
+
+ ret = snd_seq_start_queue (seq, queue, NULL);
+ if (ret < 0) {
+ GST_ERROR ("Timer event output error: %s\n", snd_strerror (ret));
+ return ret;
+ }
+
+ ret = snd_seq_drain_output (seq);
+ if (ret < 0)
+ GST_ERROR ("Drain output error: %s\n", snd_strerror (ret));
+
+ return ret;
+}
+
+static int
create_port (App * app)
{
+ snd_seq_port_info_t *pinfo;
int ret;
- ret = snd_seq_create_simple_port (app->seq, DEFAULT_CLIENT_NAME,
- SND_SEQ_PORT_CAP_WRITE |
- SND_SEQ_PORT_CAP_SUBS_WRITE,
- SND_SEQ_PORT_TYPE_MIDI_GENERIC | SND_SEQ_PORT_TYPE_APPLICATION);
+ snd_seq_port_info_alloca (&pinfo);
+ snd_seq_port_info_set_name (pinfo, DEFAULT_CLIENT_NAME);
+ snd_seq_port_info_set_type (pinfo, SND_SEQ_PORT_TYPE_MIDI_GENERIC | SND_SEQ_PORT_TYPE_APPLICATION);
+ snd_seq_port_info_set_capability (pinfo, SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE);
+
+ ret = snd_seq_alloc_queue (app->seq);
+ if (ret < 0) {
+ GST_ERROR ("Cannot allocate queue: %s\n", snd_strerror (ret));
+ return ret;
+ }
+
+ app->queue = ret;
+
+ snd_seq_port_info_set_timestamping (pinfo, 1);
+ snd_seq_port_info_set_timestamp_real (pinfo, 1);
+ snd_seq_port_info_set_timestamp_queue (pinfo, app->queue);
+
+ ret = snd_seq_create_port (app->seq, pinfo);
if (ret < 0)
GST_ERROR ("Cannot create port - %s", snd_strerror (ret));
+ ret = start_queue_timer (app->seq, app->queue);
+
return ret;
}
GST_BUFFER_DTS (buffer) = time;
GST_BUFFER_PTS (buffer) = time;
- GST_BUFFER_OFFSET (buffer) = time;
- GST_BUFFER_DURATION (buffer) = DEFAULT_TICK_PERIOD_MS * GST_MSECOND;
local_data = g_memdup (data, size);
ret = poll (app->pfds, app->npfds, DEFAULT_POLL_TIMEOUT_MS);
if (ret < 0) {
GST_ERROR ("ERROR in poll: %s", strerror (errno));
+ gst_app_src_end_of_stream (GST_APP_SRC (appsrc));
} else if (ret == 0) {
push_tick_buffer (app);
} else {
do {
snd_seq_event_t *event;
err = snd_seq_event_input (app->seq, &event);
- if (err < 0)
+ if (err < 0 && err != -EAGAIN) {
+ GST_ERROR ("Error in snd_seq_event_input: %s", snd_strerror (err));
+ gst_app_src_end_of_stream (GST_APP_SRC (appsrc));
break;
+ }
if (event) {
size_ev =
snd_midi_event_decode (app->parser, app->buffer, DEFAULT_BUFSIZE,
} else {
GST_ERROR ("Error decoding event from ALSA to output: %s",
strerror (-size_ev));
+ gst_app_src_end_of_stream (GST_APP_SRC (appsrc));
break;
}
} else {