2 * Copyright (C) 2006 Wim Taymans <wim@fluendo.com>
4 * gstjackaudioclient.c: jack audio client implementation
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
24 #include "gstjackaudioclient.h"
27 #include <gst/glib-compat-private.h>
29 GST_DEBUG_CATEGORY_STATIC (gst_jack_audio_client_debug);
30 #define GST_CAT_DEFAULT gst_jack_audio_client_debug
33 jack_log_error (const gchar * msg)
35 GST_ERROR ("%s", msg);
39 jack_info_error (const gchar * msg)
45 gst_jack_audio_client_init (void)
47 GST_DEBUG_CATEGORY_INIT (gst_jack_audio_client_debug, "jackclient", 0,
48 "jackclient helpers");
50 jack_set_error_function (jack_log_error);
51 jack_set_info_function (jack_info_error);
54 /* a list of global connections indexed by id and server. */
55 G_LOCK_DEFINE_STATIC (connections_lock);
56 static GList *connections;
58 /* the connection to a server */
65 /* id/server pair and the connection */
68 jack_client_t *client;
70 /* lists of GstJackAudioClients */
75 /* transport state handling */
77 GstState transport_state;
78 } GstJackAudioConnection;
80 /* an object sharing a jack_client_t connection. */
81 struct _GstJackAudioClient
83 GstJackAudioConnection *conn;
85 GstJackClientType type;
90 JackShutdownCallback shutdown;
91 JackProcessCallback process;
92 JackBufferSizeCallback buffer_size;
93 JackSampleRateCallback sample_rate;
99 jack_nframes_t nframes;
104 jack_handle_transport_change (GstJackAudioClient * client, GstState state)
106 GstObject *obj = GST_OBJECT_PARENT (client->user_data);
109 g_object_get (obj, "transport", &mode, NULL);
110 if ((mode & GST_JACK_TRANSPORT_SLAVE) && (GST_STATE (obj) != state)) {
111 GST_INFO_OBJECT (obj, "requesting state change: %s",
112 gst_element_state_get_name (state));
113 gst_element_post_message (GST_ELEMENT (obj),
114 gst_message_new_request_state (obj, state));
121 jack_process_cb (jack_nframes_t nframes, void *arg)
123 GstJackAudioConnection *conn = (GstJackAudioConnection *) arg;
126 jack_transport_state_t ts = jack_transport_query (conn->client, NULL);
128 if (ts != conn->cur_ts) {
131 case JackTransportStopped:
132 GST_DEBUG ("transport state is 'stopped'");
133 conn->transport_state = GST_STATE_PAUSED;
135 case JackTransportStarting:
136 GST_DEBUG ("transport state is 'starting'");
137 conn->transport_state = GST_STATE_READY;
139 case JackTransportRolling:
140 GST_DEBUG ("transport state is 'rolling'");
141 conn->transport_state = GST_STATE_PLAYING;
146 GST_DEBUG ("num of clients: src=%d, sink=%d",
147 g_list_length (conn->src_clients), g_list_length (conn->sink_clients));
150 g_mutex_lock (&conn->lock);
151 /* call sources first, then sinks. Sources will either push data into the
152 * ringbuffer of the sinks, which will then pull the data out of it, or
153 * sinks will pull the data from the sources. */
154 for (walk = conn->src_clients; walk; walk = g_list_next (walk)) {
155 GstJackAudioClient *client = (GstJackAudioClient *) walk->data;
157 /* only call active clients */
158 if ((client->active || client->deactivate) && client->process) {
159 res = client->process (nframes, client->user_data);
160 if (client->deactivate) {
161 client->deactivate = FALSE;
162 g_cond_signal (&conn->flush_cond);
166 for (walk = conn->sink_clients; walk; walk = g_list_next (walk)) {
167 GstJackAudioClient *client = (GstJackAudioClient *) walk->data;
169 /* only call active clients */
170 if ((client->active || client->deactivate) && client->process) {
171 res = client->process (nframes, client->user_data);
172 if (client->deactivate) {
173 client->deactivate = FALSE;
174 g_cond_signal (&conn->flush_cond);
179 /* handle transport state requisition, do sinks first, stop after the first
180 * element that handled it */
181 if (conn->transport_state != GST_STATE_VOID_PENDING) {
182 for (walk = conn->sink_clients; walk; walk = g_list_next (walk)) {
183 if (jack_handle_transport_change ((GstJackAudioClient *) walk->data,
184 conn->transport_state)) {
185 conn->transport_state = GST_STATE_VOID_PENDING;
190 if (conn->transport_state != GST_STATE_VOID_PENDING) {
191 for (walk = conn->src_clients; walk; walk = g_list_next (walk)) {
192 if (jack_handle_transport_change ((GstJackAudioClient *) walk->data,
193 conn->transport_state)) {
194 conn->transport_state = GST_STATE_VOID_PENDING;
199 g_mutex_unlock (&conn->lock);
205 jack_shutdown_cb (void *arg)
207 GstJackAudioConnection *conn = (GstJackAudioConnection *) arg;
210 GST_DEBUG ("disconnect client %s from server %s", conn->id,
211 GST_STR_NULL (conn->server));
213 g_mutex_lock (&conn->lock);
214 for (walk = conn->src_clients; walk; walk = g_list_next (walk)) {
215 GstJackAudioClient *client = (GstJackAudioClient *) walk->data;
217 client->server_down = TRUE;
218 g_cond_signal (&conn->flush_cond);
219 if (client->shutdown)
220 client->shutdown (client->user_data);
222 for (walk = conn->sink_clients; walk; walk = g_list_next (walk)) {
223 GstJackAudioClient *client = (GstJackAudioClient *) walk->data;
225 client->server_down = TRUE;
226 g_cond_signal (&conn->flush_cond);
227 if (client->shutdown)
228 client->shutdown (client->user_data);
230 g_mutex_unlock (&conn->lock);
235 jack_sample_rate_cb (jack_nframes_t nframes, void *arg)
237 jack_shutdown_cb (arg);
243 jack_buffer_size_cb (jack_nframes_t nframes, void *arg)
245 jack_shutdown_cb (arg);
256 connection_find (GstJackAudioConnection * conn, FindData * data)
258 /* id's must match */
259 if (strcmp (conn->id, data->id))
262 /* both the same or NULL */
263 if (conn->server == data->server)
266 /* we cannot compare NULL */
267 if (conn->server == NULL || data->server == NULL)
270 if (strcmp (conn->server, data->server))
276 /* make a connection with @id and @server. Returns NULL on failure with the
278 static GstJackAudioConnection *
279 gst_jack_audio_make_connection (const gchar * id, const gchar * server,
280 jack_client_t * jclient, jack_status_t * status)
282 GstJackAudioConnection *conn;
283 jack_options_t options;
288 GST_DEBUG ("new client %s, connecting to server %s", id,
289 GST_STR_NULL (server));
291 /* never start a server */
292 options = JackNoStartServer;
293 /* if we have a servername, use it */
295 options |= JackServerName;
296 /* open the client */
298 jclient = jack_client_open (id, options, status, server);
302 /* now create object */
303 conn = g_new (GstJackAudioConnection, 1);
305 g_mutex_init (&conn->lock);
306 g_cond_init (&conn->flush_cond);
307 conn->id = g_strdup (id);
308 conn->server = g_strdup (server);
309 conn->client = jclient;
311 conn->src_clients = NULL;
312 conn->sink_clients = NULL;
314 conn->transport_state = GST_STATE_VOID_PENDING;
316 /* set our callbacks */
317 jack_set_process_callback (jclient, jack_process_cb, conn);
318 /* these callbacks cause us to error */
319 jack_set_buffer_size_callback (jclient, jack_buffer_size_cb, conn);
320 jack_set_sample_rate_callback (jclient, jack_sample_rate_cb, conn);
321 jack_on_shutdown (jclient, jack_shutdown_cb, conn);
323 /* all callbacks are set, activate the client */
324 GST_INFO ("activate jack_client %p", jclient);
325 if ((res = jack_activate (jclient)))
326 goto could_not_activate;
328 GST_DEBUG ("opened connection %p", conn);
335 GST_DEBUG ("failed to open jack client, %d", *status);
340 GST_ERROR ("Could not activate client (%d)", res);
341 *status = JackFailure;
342 g_mutex_clear (&conn->lock);
344 g_free (conn->server);
350 static GstJackAudioConnection *
351 gst_jack_audio_get_connection (const gchar * id, const gchar * server,
352 jack_client_t * jclient, jack_status_t * status)
354 GstJackAudioConnection *conn;
358 GST_DEBUG ("getting connection for id %s, server %s", id,
359 GST_STR_NULL (server));
362 data.server = server;
364 G_LOCK (connections_lock);
366 g_list_find_custom (connections, &data, (GCompareFunc) connection_find);
367 if (found != NULL && jclient != NULL) {
368 /* we found it, increase refcount and return it */
369 conn = (GstJackAudioConnection *) found->data;
372 GST_DEBUG ("found connection %p", conn);
374 /* make new connection */
375 conn = gst_jack_audio_make_connection (id, server, jclient, status);
377 GST_DEBUG ("created connection %p", conn);
378 /* add to list on success */
379 connections = g_list_prepend (connections, conn);
381 GST_WARNING ("could not create connection");
384 G_UNLOCK (connections_lock);
390 gst_jack_audio_unref_connection (GstJackAudioConnection * conn)
395 GST_DEBUG ("unref connection %p refcnt %d", conn, conn->refcount);
397 G_LOCK (connections_lock);
399 if ((zero = (conn->refcount == 0))) {
400 GST_DEBUG ("closing connection %p", conn);
401 /* remove from list, we can release the mutex after removing the connection
402 * from the list because after that, nobody can access the connection anymore. */
403 connections = g_list_remove (connections, conn);
405 G_UNLOCK (connections_lock);
407 /* if we are zero, close and cleanup the connection */
409 /* don't use conn->lock here. two reasons:
411 * 1) its not necessary: jack_deactivate() will not return until the JACK thread
412 * associated with this connection is cleaned up by a thread join, hence
413 * no more callbacks can occur or be in progress.
415 * 2) it would deadlock anyway, because jack_deactivate() will sleep
416 * waiting for the JACK thread, and can thus cause deadlock in
419 GST_INFO ("deactivate jack_client %p", conn->client);
420 if ((res = jack_deactivate (conn->client))) {
421 /* we only warn, this means the server is probably shut down and the client
423 GST_WARNING ("Could not deactivate Jack client (%d)", res);
425 /* close connection */
426 if ((res = jack_client_close (conn->client))) {
427 /* we assume the client is gone. */
428 GST_WARNING ("close failed (%d)", res);
432 g_mutex_clear (&conn->lock);
433 g_cond_clear (&conn->flush_cond);
435 g_free (conn->server);
441 gst_jack_audio_connection_add_client (GstJackAudioConnection * conn,
442 GstJackAudioClient * client)
444 g_mutex_lock (&conn->lock);
445 switch (client->type) {
446 case GST_JACK_CLIENT_SOURCE:
447 conn->src_clients = g_list_append (conn->src_clients, client);
450 case GST_JACK_CLIENT_SINK:
451 conn->sink_clients = g_list_append (conn->sink_clients, client);
455 g_warning ("trying to add unknown client type");
458 g_mutex_unlock (&conn->lock);
462 gst_jack_audio_connection_remove_client (GstJackAudioConnection * conn,
463 GstJackAudioClient * client)
465 g_mutex_lock (&conn->lock);
466 switch (client->type) {
467 case GST_JACK_CLIENT_SOURCE:
468 conn->src_clients = g_list_remove (conn->src_clients, client);
471 case GST_JACK_CLIENT_SINK:
472 conn->sink_clients = g_list_remove (conn->sink_clients, client);
476 g_warning ("trying to remove unknown client type");
479 g_mutex_unlock (&conn->lock);
483 * gst_jack_audio_client_get:
485 * @server: the server to connect to or NULL for the default server
486 * @type: the client type
487 * @shutdown: a callback when the jack server shuts down
488 * @process: a callback when samples are available
489 * @buffer_size: a callback when the buffer_size changes
490 * @sample_rate: a callback when the sample_rate changes
491 * @user_data: user data passed to the callbacks
492 * @status: pointer to hold the jack status code in case of errors
494 * Get the jack client connection for @id and @server. Connections to the same
495 * @id and @server will receive the same physical Jack client connection and
496 * will therefore be scheduled in the same process callback.
498 * Returns: a #GstJackAudioClient.
501 gst_jack_audio_client_new (const gchar * id, const gchar * server,
502 jack_client_t * jclient, GstJackClientType type,
503 void (*shutdown) (void *arg), JackProcessCallback process,
504 JackBufferSizeCallback buffer_size, JackSampleRateCallback sample_rate,
505 gpointer user_data, jack_status_t * status)
507 GstJackAudioClient *client;
508 GstJackAudioConnection *conn;
510 g_return_val_if_fail (id != NULL, NULL);
511 g_return_val_if_fail (status != NULL, NULL);
513 /* first get a connection for the id/server pair */
514 conn = gst_jack_audio_get_connection (id, server, jclient, status);
518 GST_INFO ("new client %s", id);
520 /* make new client using the connection */
521 client = g_new (GstJackAudioClient, 1);
522 client->active = client->deactivate = FALSE;
525 client->shutdown = shutdown;
526 client->process = process;
527 client->buffer_size = buffer_size;
528 client->sample_rate = sample_rate;
529 client->user_data = user_data;
530 client->server_down = FALSE;
532 /* add the client to the connection */
533 gst_jack_audio_connection_add_client (conn, client);
540 GST_DEBUG ("Could not get server connection (%d)", *status);
546 * gst_jack_audio_client_free:
547 * @client: a #GstJackAudioClient
549 * Free the resources used by @client.
552 gst_jack_audio_client_free (GstJackAudioClient * client)
554 GstJackAudioConnection *conn;
556 g_return_if_fail (client != NULL);
558 GST_INFO ("free client");
562 /* remove from connection first so that it's not scheduled anymore after this
564 gst_jack_audio_connection_remove_client (conn, client);
565 gst_jack_audio_unref_connection (conn);
571 * gst_jack_audio_client_get_client:
572 * @client: a #GstJackAudioClient
574 * Get the jack audio client for @client. This function is used to perform
575 * operations on the jack server from this client.
577 * Returns: The jack audio client.
580 gst_jack_audio_client_get_client (GstJackAudioClient * client)
582 g_return_val_if_fail (client != NULL, NULL);
584 /* no lock needed, the connection and the client does not change
585 * once the client is created. */
586 return client->conn->client;
590 * gst_jack_audio_client_set_active:
591 * @client: a #GstJackAudioClient
592 * @active: new mode for the client
594 * Activate or deactive @client. When a client is activated it will receive
595 * callbacks when data should be processed.
597 * Returns: 0 if all ok.
600 gst_jack_audio_client_set_active (GstJackAudioClient * client, gboolean active)
602 g_return_val_if_fail (client != NULL, -1);
604 /* make sure that we are not dispatching the client */
605 g_mutex_lock (&client->conn->lock);
606 if (client->active && !active) {
607 /* we need to process once more to flush the port */
608 client->deactivate = TRUE;
610 /* need to wait for process_cb run once more */
611 while (client->deactivate && !client->server_down)
612 g_cond_wait (&client->conn->flush_cond, &client->conn->lock);
614 client->active = active;
615 g_mutex_unlock (&client->conn->lock);
621 * gst_jack_audio_client_get_transport_state:
622 * @client: a #GstJackAudioClient
624 * Check the current transport state. The client can use this to request a state
625 * change from the application.
627 * Returns: the state, %GST_STATE_VOID_PENDING for no change in the transport
631 gst_jack_audio_client_get_transport_state (GstJackAudioClient * client)
633 GstState state = client->conn->transport_state;
635 client->conn->transport_state = GST_STATE_VOID_PENDING;