summaryrefslogtreecommitdiffstats
path: root/ext/jack/gstjackaudiosink.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/jack/gstjackaudiosink.c')
-rw-r--r--ext/jack/gstjackaudiosink.c143
1 files changed, 83 insertions, 60 deletions
diff --git a/ext/jack/gstjackaudiosink.c b/ext/jack/gstjackaudiosink.c
index b57e51cf..6f0ea571 100644
--- a/ext/jack/gstjackaudiosink.c
+++ b/ext/jack/gstjackaudiosink.c
@@ -96,8 +96,6 @@ struct _GstJackRingBuffer
gint sample_rate;
gint buffer_size;
gint channels;
-
- jack_port_t **outport;
};
struct _GstJackRingBufferClass
@@ -123,6 +121,60 @@ static gboolean gst_jack_ring_buffer_pause (GstRingBuffer * buf);
static gboolean gst_jack_ring_buffer_stop (GstRingBuffer * buf);
static guint gst_jack_ring_buffer_delay (GstRingBuffer * buf);
+static gboolean
+gst_jack_audio_sink_allocate_channels (GstJackAudioSink * sink, gint channels)
+{
+ jack_client_t *client;
+
+ client = gst_jack_audio_client_get_client (sink->client);
+
+ /* remove ports we don't need */
+ while (sink->port_count > channels) {
+ jack_port_unregister (client, sink->ports[--sink->port_count]);
+ }
+
+ /* alloc enough output ports */
+ sink->ports = g_realloc (sink->ports, sizeof (jack_port_t *) * channels);
+
+ /* create an output port for each channel */
+ while (sink->port_count < channels) {
+ gchar *name;
+
+ /* port names start from 1 */
+ name = g_strdup_printf ("out_%d", sink->port_count + 1);
+ sink->ports[sink->port_count] =
+ jack_port_register (client, name,
+ JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
+ if (sink->ports[sink->port_count] == NULL)
+ return FALSE;
+
+ sink->port_count++;
+
+ g_free (name);
+ }
+ return TRUE;
+}
+
+static void
+gst_jack_audio_sink_free_channels (GstJackAudioSink * sink)
+{
+ gint res, i = 0;
+ jack_client_t *client;
+
+ client = gst_jack_audio_client_get_client (sink->client);
+
+ /* get rid of all ports */
+ while (sink->port_count) {
+ GST_LOG_OBJECT (sink, "unregister port %d", i);
+ if ((res = jack_port_unregister (client, sink->ports[i++]))) {
+ GST_DEBUG_OBJECT (sink, "unregister of port failed (%d)", res);
+ }
+ sink->port_count--;
+ }
+ g_free (sink->ports);
+ sink->ports = NULL;
+}
+
/* ringbuffer abstract base class */
static GType
gst_jack_ring_buffer_get_type (void)
@@ -206,7 +258,7 @@ jack_process_cb (jack_nframes_t nframes, void *arg)
/* get target buffers */
for (i = 0; i < channels; i++) {
- buffers[i] = (sample_t *) jack_port_get_buffer (abuf->outport[i], nframes);
+ buffers[i] = (sample_t *) jack_port_get_buffer (sink->ports[i], nframes);
}
if (gst_ring_buffer_prepare_read (buf, &readseg, &readptr, &len)) {
@@ -343,30 +395,19 @@ static gboolean
gst_jack_ring_buffer_open_device (GstRingBuffer * buf)
{
GstJackAudioSink *sink;
- jack_options_t options;
jack_status_t status = 0;
sink = GST_JACK_AUDIO_SINK (GST_OBJECT_PARENT (buf));
GST_DEBUG_OBJECT (sink, "open");
- /* never start a server */
- options = JackNoStartServer;
- /* if we have a servername, use it */
- if (sink->server != NULL)
- options |= JackServerName;
- /* open the client */
- sink->client = jack_client_open ("GStreamer", options, &status, sink->server);
+ sink->client = gst_jack_audio_client_new ("GStreamer", sink->server,
+ GST_JACK_CLIENT_SINK,
+ jack_shutdown_cb,
+ jack_process_cb, jack_buffer_size_cb, jack_sample_rate_cb, buf, &status);
if (sink->client == NULL)
goto could_not_open;
- /* set our callbacks */
- jack_set_process_callback (sink->client, jack_process_cb, buf);
- /* these callbacks cause us to error */
- jack_set_buffer_size_callback (sink->client, jack_buffer_size_cb, buf);
- jack_set_sample_rate_callback (sink->client, jack_sample_rate_cb, buf);
- jack_on_shutdown (sink->client, jack_shutdown_cb, buf);
-
GST_DEBUG_OBJECT (sink, "opened");
return TRUE;
@@ -391,17 +432,13 @@ static gboolean
gst_jack_ring_buffer_close_device (GstRingBuffer * buf)
{
GstJackAudioSink *sink;
- gint res;
sink = GST_JACK_AUDIO_SINK (GST_OBJECT_PARENT (buf));
GST_DEBUG_OBJECT (sink, "close");
- if ((res = jack_client_close (sink->client))) {
- /* just a warning, we assume the client is gone. */
- GST_ELEMENT_WARNING (sink, RESOURCE, CLOSE,
- (NULL), ("Jack client close error (%d)", res));
- }
+ gst_jack_audio_sink_free_channels (sink);
+ gst_jack_audio_client_free (sink->client);
sink->client = NULL;
return TRUE;
@@ -426,37 +463,26 @@ gst_jack_ring_buffer_acquire (GstRingBuffer * buf, GstRingBufferSpec * spec)
const char **ports;
gint sample_rate, buffer_size;
gint i, channels, res;
+ jack_client_t *client;
sink = GST_JACK_AUDIO_SINK (GST_OBJECT_PARENT (buf));
abuf = GST_JACK_RING_BUFFER_CAST (buf);
GST_DEBUG_OBJECT (sink, "acquire");
+ client = gst_jack_audio_client_get_client (sink->client);
+
/* sample rate must be that of the server */
- sample_rate = jack_get_sample_rate (sink->client);
+ sample_rate = jack_get_sample_rate (client);
if (sample_rate != spec->rate)
goto wrong_samplerate;
channels = spec->channels;
- /* alloc enough output ports */
- abuf->outport = g_new (jack_port_t *, channels);
-
- /* create an output port for each channel */
- for (i = 0; i < channels; i++) {
- gchar *name;
-
- /* port names start from 1 */
- name = g_strdup_printf ("out_%d", i + 1);
- abuf->outport[i] = jack_port_register (sink->client, name,
- JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
- if (abuf->outport[i] == NULL)
- goto out_of_ports;
+ if (!gst_jack_audio_sink_allocate_channels (sink, channels))
+ goto out_of_ports;
- g_free (name);
- }
-
- buffer_size = jack_get_buffer_size (sink->client);
+ buffer_size = jack_get_buffer_size (client);
/* the segment size in bytes, this is large enough to hold a buffer of 32bit floats
* for all channels */
@@ -473,7 +499,7 @@ gst_jack_ring_buffer_acquire (GstRingBuffer * buf, GstRingBufferSpec * spec)
buf->data = gst_buffer_new_and_alloc (spec->segtotal * spec->segsize);
memset (GST_BUFFER_DATA (buf->data), 0, GST_BUFFER_SIZE (buf->data));
- if ((res = jack_activate (sink->client)))
+ if ((res = gst_jack_audio_client_set_active (sink->client, TRUE)))
goto could_not_activate;
/* if we need to automatically connect the ports, do so now. We must do this
@@ -482,7 +508,7 @@ gst_jack_ring_buffer_acquire (GstRingBuffer * buf, GstRingBufferSpec * spec)
/* find all the physical input ports. A physical input port is a port
* associated with a hardware device. Someone needs connect to a physical
* port in order to hear something. */
- ports = jack_get_ports (sink->client, NULL, NULL,
+ ports = jack_get_ports (client, NULL, NULL,
JackPortIsPhysical | JackPortIsInput);
if (ports == NULL) {
/* no ports? fine then we don't do anything except for posting a warning
@@ -501,7 +527,7 @@ gst_jack_ring_buffer_acquire (GstRingBuffer * buf, GstRingBufferSpec * spec)
break;
}
/* connect the port to a physical port */
- if ((res = jack_connect (sink->client, jack_port_name (abuf->outport[i]),
+ if ((res = jack_connect (client, jack_port_name (sink->ports[i]),
ports[i])))
goto cannot_connect;
}
@@ -550,30 +576,20 @@ gst_jack_ring_buffer_release (GstRingBuffer * buf)
{
GstJackAudioSink *sink;
GstJackRingBuffer *abuf;
- gint i, res;
+ gint res;
abuf = GST_JACK_RING_BUFFER_CAST (buf);
sink = GST_JACK_AUDIO_SINK (GST_OBJECT_PARENT (buf));
GST_DEBUG_OBJECT (sink, "release");
- if ((res = jack_deactivate (sink->client))) {
+ if ((res = gst_jack_audio_client_set_active (sink->client, FALSE))) {
/* we only warn, this means the server is probably shut down and the client
* is gone anyway. */
GST_ELEMENT_WARNING (sink, RESOURCE, CLOSE, (NULL),
("Could not deactivate Jack client (%d)", res));
}
- /* remove all ports */
- for (i = 0; i < abuf->channels; i++) {
- GST_LOG_OBJECT (sink, "unregister port %d", i);
- if ((res = jack_port_unregister (sink->client, abuf->outport[i]))) {
- GST_DEBUG_OBJECT (sink, "unregister of port failed (%d)", res);
- }
- abuf->outport[i] = NULL;
- }
- g_free (abuf->outport);
- abuf->outport = NULL;
abuf->channels = -1;
abuf->buffer_size = -1;
abuf->sample_rate = -1;
@@ -746,6 +762,8 @@ gst_jack_audio_sink_class_init (GstJackAudioSinkClass * klass)
gstbaseaudiosink_class->create_ringbuffer =
GST_DEBUG_FUNCPTR (gst_jack_audio_sink_create_ringbuffer);
+
+ gst_jack_audio_client_init ();
}
static void
@@ -754,6 +772,8 @@ gst_jack_audio_sink_init (GstJackAudioSink * sink,
{
sink->connect = DEFAULT_PROP_CONNECT;
sink->server = g_strdup (DEFAULT_PROP_SERVER);
+ sink->ports = NULL;
+ sink->port_count = 0;
}
static void
@@ -806,14 +826,17 @@ gst_jack_audio_sink_getcaps (GstBaseSink * bsink)
const char **ports;
gint min, max;
gint rate;
+ jack_client_t *client;
if (sink->client == NULL)
goto no_client;
+ client = gst_jack_audio_client_get_client (sink->client);
+
if (sink->connect == GST_JACK_CONNECT_AUTO) {
/* get a port count, this is the number of channels we can automatically
* connect. */
- ports = jack_get_ports (sink->client, NULL, NULL,
+ ports = jack_get_ports (client, NULL, NULL,
JackPortIsPhysical | JackPortIsInput);
max = 0;
if (ports != NULL) {
@@ -822,13 +845,13 @@ gst_jack_audio_sink_getcaps (GstBaseSink * bsink)
} else
max = 0;
} else {
- /* we allow any number of pads, somoething else is going to connect the
+ /* we allow any number of pads, something else is going to connect the
* pads. */
max = G_MAXINT;
}
min = MIN (1, max);
- rate = jack_get_sample_rate (sink->client);
+ rate = jack_get_sample_rate (client);
GST_DEBUG_OBJECT (sink, "got %d-%d ports, samplerate: %d", min, max, rate);