1 /* GStreamer
2 * Copyright (C) 2006 Wim Taymans <wim@fluendo.com>
3 *
4 * gstjackaudiosink.c: jack audio sink implementation
5 *
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.
10 *
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.
15 *
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.
20 */
21
22 /**
23 * SECTION:element-jackaudiosink
24 * @title: jackaudiosink
25 * @see_also: #GstAudioBaseSink, #GstAudioRingBuffer
26 *
27 * A Sink that outputs data to Jack ports.
28 *
29 * It will create N Jack ports named out_<name>_<num> where
30 * <name> is the element name and <num> is starting from 1.
31 * Each port corresponds to a gstreamer channel.
32 *
33 * The samplerate as exposed on the caps is always the same as the samplerate of
34 * the jack server.
35 *
36 * When the #GstJackAudioSink:connect property is set to auto, this element
37 * will try to connect each output port to a random physical jack input pin. In
38 * this mode, the sink will expose the number of physical channels on its pad
39 * caps.
40 *
41 * When the #GstJackAudioSink:connect property is set to none, the element will
42 * accept any number of input channels and will create (but not connect) an
43 * output port for each channel.
44 *
45 * The element will generate an error when the Jack server is shut down when it
46 * was PAUSED or PLAYING. This element does not support dynamic rate and buffer
47 * size changes at runtime.
48 *
49 * ## Example launch line
50 * |[
51 * gst-launch-1.0 audiotestsrc ! jackaudiosink
52 * ]| Play a sine wave to using jack.
53 *
54 */
55
56 #ifdef HAVE_CONFIG_H
57 #include "config.h"
58 #endif
59
60 #include <gst/gst-i18n-plugin.h>
61 #include <stdlib.h>
62 #include <string.h>
63 #include <gst/audio/audio.h>
64
65 #include "gstjackaudiosink.h"
66 #include "gstjackringbuffer.h"
67
68 GST_DEBUG_CATEGORY_STATIC (gst_jack_audio_sink_debug);
69 #define GST_CAT_DEFAULT gst_jack_audio_sink_debug
70
71 static gboolean
gst_jack_audio_sink_allocate_channels(GstJackAudioSink * sink,gint channels)72 gst_jack_audio_sink_allocate_channels (GstJackAudioSink * sink, gint channels)
73 {
74 jack_client_t *client;
75
76 client = gst_jack_audio_client_get_client (sink->client);
77
78 /* remove ports we don't need */
79 while (sink->port_count > channels) {
80 jack_port_unregister (client, sink->ports[--sink->port_count]);
81 }
82
83 /* alloc enough output ports */
84 sink->ports = g_realloc (sink->ports, sizeof (jack_port_t *) * channels);
85 sink->buffers = g_realloc (sink->buffers, sizeof (sample_t *) * channels);
86
87 /* create an output port for each channel */
88 while (sink->port_count < channels) {
89 gchar *name;
90
91 /* port names start from 1 and are local to the element */
92 name =
93 g_strdup_printf ("out_%s_%d", GST_ELEMENT_NAME (sink),
94 sink->port_count + 1);
95 sink->ports[sink->port_count] =
96 jack_port_register (client, name, JACK_DEFAULT_AUDIO_TYPE,
97 JackPortIsOutput, 0);
98 if (sink->ports[sink->port_count] == NULL)
99 return FALSE;
100
101 sink->port_count++;
102
103 g_free (name);
104 }
105 return TRUE;
106 }
107
108 static void
gst_jack_audio_sink_free_channels(GstJackAudioSink * sink)109 gst_jack_audio_sink_free_channels (GstJackAudioSink * sink)
110 {
111 gint res, i = 0;
112 jack_client_t *client;
113
114 client = gst_jack_audio_client_get_client (sink->client);
115
116 /* get rid of all ports */
117 while (sink->port_count) {
118 GST_LOG_OBJECT (sink, "unregister port %d", i);
119 if ((res = jack_port_unregister (client, sink->ports[i++]))) {
120 GST_DEBUG_OBJECT (sink, "unregister of port failed (%d)", res);
121 }
122 sink->port_count--;
123 }
124 g_free (sink->ports);
125 sink->ports = NULL;
126 g_free (sink->buffers);
127 sink->buffers = NULL;
128 }
129
130 /* ringbuffer abstract base class */
131 static GType
gst_jack_ring_buffer_get_type(void)132 gst_jack_ring_buffer_get_type (void)
133 {
134 static gsize ringbuffer_type = 0;
135
136 if (g_once_init_enter (&ringbuffer_type)) {
137 static const GTypeInfo ringbuffer_info = {
138 sizeof (GstJackRingBufferClass),
139 NULL,
140 NULL,
141 (GClassInitFunc) gst_jack_ring_buffer_class_init,
142 NULL,
143 NULL,
144 sizeof (GstJackRingBuffer),
145 0,
146 (GInstanceInitFunc) gst_jack_ring_buffer_init,
147 NULL
148 };
149 GType tmp = g_type_register_static (GST_TYPE_AUDIO_RING_BUFFER,
150 "GstJackAudioSinkRingBuffer", &ringbuffer_info, 0);
151 g_once_init_leave (&ringbuffer_type, tmp);
152 }
153
154 return (GType) ringbuffer_type;
155 }
156
157 static void
gst_jack_ring_buffer_class_init(GstJackRingBufferClass * klass)158 gst_jack_ring_buffer_class_init (GstJackRingBufferClass * klass)
159 {
160 GstAudioRingBufferClass *gstringbuffer_class;
161
162 gstringbuffer_class = (GstAudioRingBufferClass *) klass;
163
164 ring_parent_class = g_type_class_peek_parent (klass);
165
166 gstringbuffer_class->open_device =
167 GST_DEBUG_FUNCPTR (gst_jack_ring_buffer_open_device);
168 gstringbuffer_class->close_device =
169 GST_DEBUG_FUNCPTR (gst_jack_ring_buffer_close_device);
170 gstringbuffer_class->acquire =
171 GST_DEBUG_FUNCPTR (gst_jack_ring_buffer_acquire);
172 gstringbuffer_class->release =
173 GST_DEBUG_FUNCPTR (gst_jack_ring_buffer_release);
174 gstringbuffer_class->start = GST_DEBUG_FUNCPTR (gst_jack_ring_buffer_start);
175 gstringbuffer_class->pause = GST_DEBUG_FUNCPTR (gst_jack_ring_buffer_pause);
176 gstringbuffer_class->resume = GST_DEBUG_FUNCPTR (gst_jack_ring_buffer_start);
177 gstringbuffer_class->stop = GST_DEBUG_FUNCPTR (gst_jack_ring_buffer_stop);
178
179 gstringbuffer_class->delay = GST_DEBUG_FUNCPTR (gst_jack_ring_buffer_delay);
180
181 gst_type_mark_as_plugin_api (GST_TYPE_JACK_CONNECT, 0);
182 gst_type_mark_as_plugin_api (GST_TYPE_JACK_TRANSPORT, 0);
183 }
184
185 /* this is the callback of jack. This should RT-safe.
186 */
187 static int
jack_process_cb(jack_nframes_t nframes,void * arg)188 jack_process_cb (jack_nframes_t nframes, void *arg)
189 {
190 GstJackAudioSink *sink;
191 GstAudioRingBuffer *buf;
192 gint readseg, len;
193 guint8 *readptr;
194 gint i, j, flen, channels;
195 sample_t *data;
196
197 buf = GST_AUDIO_RING_BUFFER_CAST (arg);
198 sink = GST_JACK_AUDIO_SINK (GST_OBJECT_PARENT (buf));
199
200 channels = GST_AUDIO_INFO_CHANNELS (&buf->spec.info);
201
202 /* get target buffers */
203 for (i = 0; i < channels; i++) {
204 sink->buffers[i] =
205 (sample_t *) jack_port_get_buffer (sink->ports[i], nframes);
206 }
207
208 if (gst_audio_ring_buffer_prepare_read (buf, &readseg, &readptr, &len)) {
209 flen = len / channels;
210
211 /* the number of samples must be exactly the segment size */
212 if (nframes * sizeof (sample_t) != flen)
213 goto wrong_size;
214
215 GST_DEBUG_OBJECT (sink, "copy %d frames: %p, %d bytes, %d channels",
216 nframes, readptr, flen, channels);
217 data = (sample_t *) readptr;
218
219 /* the samples in the ringbuffer have the channels interleaved, we need to
220 * deinterleave into the jack target buffers */
221 for (i = 0; i < nframes; i++) {
222 for (j = 0; j < channels; j++) {
223 sink->buffers[j][i] = *data++;
224 }
225 }
226
227 /* clear written samples in the ringbuffer */
228 gst_audio_ring_buffer_clear (buf, readseg);
229
230 /* we wrote one segment */
231 gst_audio_ring_buffer_advance (buf, 1);
232 } else {
233 GST_DEBUG_OBJECT (sink, "write %d frames silence", nframes);
234 /* We are not allowed to read from the ringbuffer, write silence to all
235 * jack output buffers */
236 for (i = 0; i < channels; i++) {
237 memset (sink->buffers[i], 0, nframes * sizeof (sample_t));
238 }
239 }
240 return 0;
241
242 /* ERRORS */
243 wrong_size:
244 {
245 GST_ERROR_OBJECT (sink, "nbytes (%d) != flen (%d)",
246 (gint) (nframes * sizeof (sample_t)), flen);
247 return 1;
248 }
249 }
250
251 /* we error out */
252 static int
jack_sample_rate_cb(jack_nframes_t nframes,void * arg)253 jack_sample_rate_cb (jack_nframes_t nframes, void *arg)
254 {
255 GstJackAudioSink *sink;
256 GstJackRingBuffer *abuf;
257
258 abuf = GST_JACK_RING_BUFFER_CAST (arg);
259 sink = GST_JACK_AUDIO_SINK (GST_OBJECT_PARENT (arg));
260
261 if (abuf->sample_rate != -1 && abuf->sample_rate != nframes)
262 goto not_supported;
263
264 return 0;
265
266 /* ERRORS */
267 not_supported:
268 {
269 GST_ELEMENT_ERROR (sink, RESOURCE, SETTINGS,
270 (NULL), ("Jack changed the sample rate, which is not supported"));
271 return 1;
272 }
273 }
274
275 /* we error out */
276 static int
jack_buffer_size_cb(jack_nframes_t nframes,void * arg)277 jack_buffer_size_cb (jack_nframes_t nframes, void *arg)
278 {
279 GstJackAudioSink *sink;
280 GstJackRingBuffer *abuf;
281
282 abuf = GST_JACK_RING_BUFFER_CAST (arg);
283 sink = GST_JACK_AUDIO_SINK (GST_OBJECT_PARENT (arg));
284
285 if (abuf->buffer_size != -1 && abuf->buffer_size != nframes)
286 goto not_supported;
287
288 return 0;
289
290 /* ERRORS */
291 not_supported:
292 {
293 GST_ELEMENT_ERROR (sink, RESOURCE, SETTINGS,
294 (NULL), ("Jack changed the buffer size, which is not supported"));
295 return 1;
296 }
297 }
298
299 static void
jack_shutdown_cb(void * arg)300 jack_shutdown_cb (void *arg)
301 {
302 GstJackAudioSink *sink;
303
304 sink = GST_JACK_AUDIO_SINK (GST_OBJECT_PARENT (arg));
305
306 GST_DEBUG_OBJECT (sink, "shutdown");
307
308 GST_ELEMENT_ERROR (sink, RESOURCE, NOT_FOUND,
309 (NULL), ("Jack server shutdown"));
310 }
311
312 static void
gst_jack_ring_buffer_init(GstJackRingBuffer * buf,GstJackRingBufferClass * g_class)313 gst_jack_ring_buffer_init (GstJackRingBuffer * buf,
314 GstJackRingBufferClass * g_class)
315 {
316 buf->channels = -1;
317 buf->buffer_size = -1;
318 buf->sample_rate = -1;
319 }
320
321 /* the _open_device method should make a connection with the server
322 */
323 static gboolean
gst_jack_ring_buffer_open_device(GstAudioRingBuffer * buf)324 gst_jack_ring_buffer_open_device (GstAudioRingBuffer * buf)
325 {
326 GstJackAudioSink *sink;
327 jack_status_t status = 0;
328 const gchar *name;
329
330 sink = GST_JACK_AUDIO_SINK (GST_OBJECT_PARENT (buf));
331
332 GST_DEBUG_OBJECT (sink, "open");
333
334 if (sink->client_name) {
335 name = sink->client_name;
336 } else {
337 name = g_get_application_name ();
338 }
339 if (!name)
340 name = "GStreamer";
341
342 sink->client = gst_jack_audio_client_new (name, sink->server,
343 sink->jclient,
344 GST_JACK_CLIENT_SINK,
345 jack_shutdown_cb,
346 jack_process_cb, jack_buffer_size_cb, jack_sample_rate_cb, buf, &status);
347 if (sink->client == NULL)
348 goto could_not_open;
349
350 GST_DEBUG_OBJECT (sink, "opened");
351
352 return TRUE;
353
354 /* ERRORS */
355 could_not_open:
356 {
357 if (status & JackServerFailed) {
358 GST_ELEMENT_ERROR (sink, RESOURCE, NOT_FOUND,
359 (_("Jack server not found")),
360 ("Cannot connect to the Jack server (status %d)", status));
361 } else {
362 GST_ELEMENT_ERROR (sink, RESOURCE, OPEN_WRITE,
363 (NULL), ("Jack client open error (status %d)", status));
364 }
365 return FALSE;
366 }
367 }
368
369 /* close the connection with the server
370 */
371 static gboolean
gst_jack_ring_buffer_close_device(GstAudioRingBuffer * buf)372 gst_jack_ring_buffer_close_device (GstAudioRingBuffer * buf)
373 {
374 GstJackAudioSink *sink;
375
376 sink = GST_JACK_AUDIO_SINK (GST_OBJECT_PARENT (buf));
377
378 GST_DEBUG_OBJECT (sink, "close");
379
380 gst_jack_audio_sink_free_channels (sink);
381 gst_jack_audio_client_free (sink->client);
382 sink->client = NULL;
383
384 return TRUE;
385 }
386
387 /* allocate a buffer and setup resources to process the audio samples of
388 * the format as specified in @spec.
389 *
390 * We allocate N jack ports, one for each channel. If we are asked to
391 * automatically make a connection with physical ports, we connect as many
392 * ports as there are physical ports, leaving leftover ports unconnected.
393 *
394 * It is assumed that samplerate and number of channels are acceptable since our
395 * getcaps method will always provide correct values. If unacceptable caps are
396 * received for some reason, we fail here.
397 */
398 static gboolean
gst_jack_ring_buffer_acquire(GstAudioRingBuffer * buf,GstAudioRingBufferSpec * spec)399 gst_jack_ring_buffer_acquire (GstAudioRingBuffer * buf,
400 GstAudioRingBufferSpec * spec)
401 {
402 GstJackAudioSink *sink;
403 GstJackRingBuffer *abuf;
404 gint sample_rate, buffer_size;
405 gint i, rate, bpf, channels, res;
406 jack_client_t *client;
407
408 sink = GST_JACK_AUDIO_SINK (GST_OBJECT_PARENT (buf));
409 abuf = GST_JACK_RING_BUFFER_CAST (buf);
410
411 GST_DEBUG_OBJECT (sink, "acquire");
412
413 client = gst_jack_audio_client_get_client (sink->client);
414
415 rate = GST_AUDIO_INFO_RATE (&spec->info);
416
417 /* sample rate must be that of the server */
418 sample_rate = jack_get_sample_rate (client);
419 if (sample_rate != rate)
420 goto wrong_samplerate;
421
422 channels = GST_AUDIO_INFO_CHANNELS (&spec->info);
423 bpf = GST_AUDIO_INFO_BPF (&spec->info);
424
425 if (!gst_jack_audio_sink_allocate_channels (sink, channels))
426 goto out_of_ports;
427
428 buffer_size = jack_get_buffer_size (client);
429
430 /* the segment size in bytes, this is large enough to hold a buffer of 32bit floats
431 * for all channels */
432 spec->segsize = buffer_size * sizeof (gfloat) * channels;
433 spec->latency_time = gst_util_uint64_scale (spec->segsize,
434 (GST_SECOND / GST_USECOND), rate * bpf);
435 /* segtotal based on buffer-time latency */
436 spec->segtotal = spec->buffer_time / spec->latency_time;
437
438 /* Use small period when low-latency is enabled regardless of buffer-time */
439 if (spec->segtotal < 2 || sink->low_latency) {
440 spec->segtotal = 2;
441 spec->buffer_time = spec->latency_time * spec->segtotal;
442 }
443
444 GST_DEBUG_OBJECT (sink, "buffer time: %" G_GINT64_FORMAT " usec",
445 spec->buffer_time);
446 GST_DEBUG_OBJECT (sink, "latency time: %" G_GINT64_FORMAT " usec",
447 spec->latency_time);
448 GST_DEBUG_OBJECT (sink, "buffer_size %d, segsize %d, segtotal %d",
449 buffer_size, spec->segsize, spec->segtotal);
450
451 /* allocate the ringbuffer memory now */
452 buf->size = spec->segtotal * spec->segsize;
453 buf->memory = g_malloc0 (buf->size);
454
455 if ((res = gst_jack_audio_client_set_active (sink->client, TRUE)))
456 goto could_not_activate;
457
458 /* if we need to automatically connect the ports, do so now. We must do this
459 * after activating the client. */
460 if (sink->connect == GST_JACK_CONNECT_AUTO
461 || sink->connect == GST_JACK_CONNECT_AUTO_FORCED
462 || sink->connect == GST_JACK_CONNECT_EXPLICIT) {
463 const char **available_ports = NULL;
464 const char **jack_ports = NULL;
465 char **user_ports = NULL;
466
467 /* find all the physical input ports. A physical input port is a port
468 * associated with a hardware device. Someone needs connect to a physical
469 * port in order to hear something. */
470 if (sink->port_names) {
471 user_ports = gst_jack_audio_client_get_port_names_from_string (client,
472 sink->port_names, JackPortIsInput);
473
474 if (user_ports)
475 available_ports = (const char **) user_ports;
476 }
477
478 if (!available_ports && sink->connect == GST_JACK_CONNECT_EXPLICIT)
479 goto wrong_port_names;
480
481 if (!available_ports) {
482 if (!sink->port_pattern) {
483 jack_ports = jack_get_ports (client, NULL, NULL,
484 JackPortIsPhysical | JackPortIsInput);
485 } else {
486 jack_ports = jack_get_ports (client, sink->port_pattern, NULL,
487 JackPortIsInput);
488 }
489
490 available_ports = jack_ports;
491 }
492
493 if (!available_ports) {
494 /* no ports? fine then we don't do anything except for posting a warning
495 * message. */
496 GST_ELEMENT_WARNING (sink, RESOURCE, NOT_FOUND, (NULL),
497 ("No physical input ports found, leaving ports unconnected"));
498 goto done;
499 }
500
501 for (i = 0; i < channels; i++) {
502 /* stop when all input ports are exhausted */
503 if (!available_ports[i]) {
504 /* post a warning that we could not connect all ports */
505 GST_ELEMENT_WARNING (sink, RESOURCE, NOT_FOUND, (NULL),
506 ("No more physical ports, leaving some ports unconnected"));
507 break;
508 }
509 GST_DEBUG_OBJECT (sink, "try connecting to %s",
510 jack_port_name (sink->ports[i]));
511 /* connect the port to a physical port */
512 res = jack_connect (client,
513 jack_port_name (sink->ports[i]), available_ports[i]);
514 if (res != 0 && res != EEXIST) {
515 jack_free (jack_ports);
516 g_strfreev (user_ports);
517
518 goto cannot_connect;
519 }
520 }
521
522 jack_free (jack_ports);
523 g_strfreev (user_ports);
524 }
525 done:
526
527 abuf->sample_rate = sample_rate;
528 abuf->buffer_size = buffer_size;
529 abuf->channels = channels;
530
531 return TRUE;
532
533 /* ERRORS */
534 wrong_samplerate:
535 {
536 GST_ELEMENT_ERROR (sink, RESOURCE, SETTINGS, (NULL),
537 ("Wrong samplerate, server is running at %d and we received %d",
538 sample_rate, rate));
539 return FALSE;
540 }
541 out_of_ports:
542 {
543 GST_ELEMENT_ERROR (sink, RESOURCE, SETTINGS, (NULL),
544 ("Cannot allocate more Jack ports"));
545 return FALSE;
546 }
547 could_not_activate:
548 {
549 GST_ELEMENT_ERROR (sink, RESOURCE, SETTINGS, (NULL),
550 ("Could not activate client (%d:%s)", res, g_strerror (res)));
551 return FALSE;
552 }
553 cannot_connect:
554 {
555 GST_ELEMENT_ERROR (sink, RESOURCE, SETTINGS, (NULL),
556 ("Could not connect output ports to physical ports (%d:%s)",
557 res, g_strerror (res)));
558 return FALSE;
559 }
560 wrong_port_names:
561 {
562 GST_ELEMENT_ERROR (sink, RESOURCE, SETTINGS, (NULL),
563 ("Invalid port-names was provided"));
564 return FALSE;
565 }
566 }
567
568 /* function is called with LOCK */
569 static gboolean
gst_jack_ring_buffer_release(GstAudioRingBuffer * buf)570 gst_jack_ring_buffer_release (GstAudioRingBuffer * buf)
571 {
572 GstJackAudioSink *sink;
573 GstJackRingBuffer *abuf;
574 gint res;
575
576 abuf = GST_JACK_RING_BUFFER_CAST (buf);
577 sink = GST_JACK_AUDIO_SINK (GST_OBJECT_PARENT (buf));
578
579 GST_DEBUG_OBJECT (sink, "release");
580
581 if ((res = gst_jack_audio_client_set_active (sink->client, FALSE))) {
582 /* we only warn, this means the server is probably shut down and the client
583 * is gone anyway. */
584 GST_ELEMENT_WARNING (sink, RESOURCE, CLOSE, (NULL),
585 ("Could not deactivate Jack client (%d)", res));
586 }
587
588 abuf->channels = -1;
589 abuf->buffer_size = -1;
590 abuf->sample_rate = -1;
591
592 /* free the buffer */
593 g_free (buf->memory);
594 buf->memory = NULL;
595
596 return TRUE;
597 }
598
599 static gboolean
gst_jack_ring_buffer_start(GstAudioRingBuffer * buf)600 gst_jack_ring_buffer_start (GstAudioRingBuffer * buf)
601 {
602 GstJackAudioSink *sink;
603
604 sink = GST_JACK_AUDIO_SINK (GST_OBJECT_PARENT (buf));
605
606 GST_DEBUG_OBJECT (sink, "start");
607
608 if (sink->transport & GST_JACK_TRANSPORT_MASTER) {
609 jack_client_t *client;
610
611 client = gst_jack_audio_client_get_client (sink->client);
612 jack_transport_start (client);
613 }
614
615 return TRUE;
616 }
617
618 static gboolean
gst_jack_ring_buffer_pause(GstAudioRingBuffer * buf)619 gst_jack_ring_buffer_pause (GstAudioRingBuffer * buf)
620 {
621 GstJackAudioSink *sink;
622
623 sink = GST_JACK_AUDIO_SINK (GST_OBJECT_PARENT (buf));
624
625 GST_DEBUG_OBJECT (sink, "pause");
626
627 if (sink->transport & GST_JACK_TRANSPORT_MASTER) {
628 jack_client_t *client;
629
630 client = gst_jack_audio_client_get_client (sink->client);
631 jack_transport_stop (client);
632 }
633
634 return TRUE;
635 }
636
637 static gboolean
gst_jack_ring_buffer_stop(GstAudioRingBuffer * buf)638 gst_jack_ring_buffer_stop (GstAudioRingBuffer * buf)
639 {
640 GstJackAudioSink *sink;
641
642 sink = GST_JACK_AUDIO_SINK (GST_OBJECT_PARENT (buf));
643
644 GST_DEBUG_OBJECT (sink, "stop");
645
646 if (sink->transport & GST_JACK_TRANSPORT_MASTER) {
647 jack_client_t *client;
648
649 client = gst_jack_audio_client_get_client (sink->client);
650 jack_transport_stop (client);
651 }
652
653 return TRUE;
654 }
655
656 #if defined (HAVE_JACK_0_120_1) || defined(HAVE_JACK_1_9_7)
657 static guint
gst_jack_ring_buffer_delay(GstAudioRingBuffer * buf)658 gst_jack_ring_buffer_delay (GstAudioRingBuffer * buf)
659 {
660 GstJackAudioSink *sink;
661 guint i, res = 0;
662 jack_latency_range_t range;
663
664 sink = GST_JACK_AUDIO_SINK (GST_OBJECT_PARENT (buf));
665
666 for (i = 0; i < sink->port_count; i++) {
667 jack_port_get_latency_range (sink->ports[i], JackPlaybackLatency, &range);
668 if (range.max > res)
669 res = range.max;
670 }
671
672 GST_LOG_OBJECT (sink, "delay %u", res);
673
674 return res;
675 }
676 #else /* !(defined (HAVE_JACK_0_120_1) || defined(HAVE_JACK_1_9_7)) */
677 static guint
gst_jack_ring_buffer_delay(GstAudioRingBuffer * buf)678 gst_jack_ring_buffer_delay (GstAudioRingBuffer * buf)
679 {
680 GstJackAudioSink *sink;
681 guint i, res = 0;
682 guint latency;
683 jack_client_t *client;
684
685 sink = GST_JACK_AUDIO_SINK (GST_OBJECT_PARENT (buf));
686 client = gst_jack_audio_client_get_client (sink->client);
687
688 for (i = 0; i < sink->port_count; i++) {
689 latency = jack_port_get_total_latency (client, sink->ports[i]);
690 if (latency > res)
691 res = latency;
692 }
693
694 GST_LOG_OBJECT (sink, "delay %u", res);
695
696 return res;
697 }
698 #endif
699
700 static GstStaticPadTemplate jackaudiosink_sink_factory =
701 GST_STATIC_PAD_TEMPLATE ("sink",
702 GST_PAD_SINK,
703 GST_PAD_ALWAYS,
704 GST_STATIC_CAPS ("audio/x-raw, "
705 "format = (string) " GST_JACK_FORMAT_STR ", "
706 "layout = (string) interleaved, "
707 "rate = (int) [ 1, MAX ], " "channels = (int) [ 1, MAX ]")
708 );
709
710 /* AudioSink signals and args */
711 enum
712 {
713 /* FILL ME */
714 SIGNAL_LAST
715 };
716
717 #define DEFAULT_PROP_CONNECT GST_JACK_CONNECT_AUTO
718 #define DEFAULT_PROP_SERVER NULL
719 #define DEFAULT_PROP_CLIENT_NAME NULL
720 #define DEFAULT_PROP_PORT_PATTERN NULL
721 #define DEFAULT_PROP_TRANSPORT GST_JACK_TRANSPORT_AUTONOMOUS
722 #define DEFAULT_PROP_LOW_LATENCY FALSE
723
724 enum
725 {
726 PROP_0,
727 PROP_CONNECT,
728 PROP_SERVER,
729 PROP_CLIENT,
730 PROP_CLIENT_NAME,
731 PROP_PORT_PATTERN,
732 PROP_TRANSPORT,
733 PROP_LOW_LATENCY,
734 PROP_PORT_NAMES,
735 PROP_LAST
736 };
737
738 #define gst_jack_audio_sink_parent_class parent_class
739 G_DEFINE_TYPE (GstJackAudioSink, gst_jack_audio_sink, GST_TYPE_AUDIO_BASE_SINK);
740 GST_ELEMENT_REGISTER_DEFINE (jackaudiosink, "jackaudiosink",
741 GST_RANK_PRIMARY, GST_TYPE_JACK_AUDIO_SINK);
742
743 static void gst_jack_audio_sink_dispose (GObject * object);
744 static void gst_jack_audio_sink_set_property (GObject * object, guint prop_id,
745 const GValue * value, GParamSpec * pspec);
746 static void gst_jack_audio_sink_get_property (GObject * object, guint prop_id,
747 GValue * value, GParamSpec * pspec);
748
749 static GstCaps *gst_jack_audio_sink_getcaps (GstBaseSink * bsink,
750 GstCaps * filter);
751 static GstAudioRingBuffer
752 * gst_jack_audio_sink_create_ringbuffer (GstAudioBaseSink * sink);
753
754 static void
gst_jack_audio_sink_class_init(GstJackAudioSinkClass * klass)755 gst_jack_audio_sink_class_init (GstJackAudioSinkClass * klass)
756 {
757 GObjectClass *gobject_class;
758 GstElementClass *gstelement_class;
759 GstBaseSinkClass *gstbasesink_class;
760 GstAudioBaseSinkClass *gstaudiobasesink_class;
761
762 GST_DEBUG_CATEGORY_INIT (gst_jack_audio_sink_debug, "jacksink", 0,
763 "jacksink element");
764
765 gobject_class = (GObjectClass *) klass;
766 gstelement_class = (GstElementClass *) klass;
767 gstbasesink_class = (GstBaseSinkClass *) klass;
768 gstaudiobasesink_class = (GstAudioBaseSinkClass *) klass;
769
770 gobject_class->dispose = gst_jack_audio_sink_dispose;
771 gobject_class->get_property = gst_jack_audio_sink_get_property;
772 gobject_class->set_property = gst_jack_audio_sink_set_property;
773
774 g_object_class_install_property (gobject_class, PROP_CONNECT,
775 g_param_spec_enum ("connect", "Connect",
776 "Specify how the output ports will be connected",
777 GST_TYPE_JACK_CONNECT, DEFAULT_PROP_CONNECT,
778 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
779
780 g_object_class_install_property (gobject_class, PROP_SERVER,
781 g_param_spec_string ("server", "Server",
782 "The Jack server to connect to (NULL = default)",
783 DEFAULT_PROP_SERVER, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
784
785 /**
786 * GstJackAudioSink:client-name:
787 *
788 * The client name to use.
789 */
790 g_object_class_install_property (gobject_class, PROP_CLIENT_NAME,
791 g_param_spec_string ("client-name", "Client name",
792 "The client name of the Jack instance (NULL = default)",
793 DEFAULT_PROP_CLIENT_NAME,
794 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
795
796 g_object_class_install_property (gobject_class, PROP_CLIENT,
797 g_param_spec_boxed ("client", "JackClient", "Handle for jack client",
798 GST_TYPE_JACK_CLIENT,
799 GST_PARAM_MUTABLE_READY | G_PARAM_READWRITE |
800 G_PARAM_STATIC_STRINGS));
801
802 /**
803 * GstJackAudioSink:port-pattern
804 *
805 * autoconnect to ports matching pattern, when NULL connect to physical ports
806 *
807 * Since: 1.6
808 */
809 g_object_class_install_property (gobject_class, PROP_PORT_PATTERN,
810 g_param_spec_string ("port-pattern", "port pattern",
811 "A pattern to select which ports to connect to (NULL = first physical ports)",
812 DEFAULT_PROP_PORT_PATTERN,
813 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
814
815 /**
816 * GstJackAudioSink:transport:
817 *
818 * The jack transport behaviour for the client.
819 */
820 g_object_class_install_property (gobject_class, PROP_TRANSPORT,
821 g_param_spec_flags ("transport", "Transport mode",
822 "Jack transport behaviour of the client",
823 GST_TYPE_JACK_TRANSPORT, DEFAULT_PROP_TRANSPORT,
824 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
825
826 /**
827 * GstJackAudioSink:low-latency:
828 *
829 * Optimize all settings for lowest latency. When enabled,
830 * #GstAudioBaseSink:buffer-time and #GstAudioBaseSink:latency-time will be
831 * ignored.
832 *
833 * Since: 1.20
834 */
835 g_object_class_install_property (gobject_class, PROP_LOW_LATENCY,
836 g_param_spec_boolean ("low-latency", "Low latency",
837 "Optimize all settings for lowest latency. When enabled, "
838 "\"buffer-time\" and \"latency-time\" will be ignored",
839 DEFAULT_PROP_LOW_LATENCY,
840 GST_PARAM_MUTABLE_READY | G_PARAM_READWRITE |
841 G_PARAM_STATIC_STRINGS));
842
843 /**
844 * GstJackAudioSink:port-names:
845 *
846 * Comma-separated list of port name including "client_name:" prefix
847 *
848 * Since: 1.20
849 */
850 g_object_class_install_property (gobject_class, PROP_PORT_NAMES,
851 g_param_spec_string ("port-names", "Port Names",
852 "Comma-separated list of port name including \"client_name:\" prefix",
853 NULL, GST_PARAM_MUTABLE_READY | G_PARAM_READWRITE |
854 G_PARAM_STATIC_STRINGS));
855
856 gst_element_class_set_static_metadata (gstelement_class, "Audio Sink (Jack)",
857 "Sink/Audio", "Output audio to a JACK server",
858 "Wim Taymans <wim.taymans@gmail.com>");
859
860 gst_element_class_add_static_pad_template (gstelement_class,
861 &jackaudiosink_sink_factory);
862
863 gstbasesink_class->get_caps = GST_DEBUG_FUNCPTR (gst_jack_audio_sink_getcaps);
864
865 gstaudiobasesink_class->create_ringbuffer =
866 GST_DEBUG_FUNCPTR (gst_jack_audio_sink_create_ringbuffer);
867
868 /* ref class from a thread-safe context to work around missing bit of
869 * thread-safety in GObject */
870 g_type_class_ref (GST_TYPE_JACK_RING_BUFFER);
871
872 gst_jack_audio_client_init ();
873 }
874
875 static void
gst_jack_audio_sink_init(GstJackAudioSink * sink)876 gst_jack_audio_sink_init (GstJackAudioSink * sink)
877 {
878 sink->connect = DEFAULT_PROP_CONNECT;
879 sink->server = g_strdup (DEFAULT_PROP_SERVER);
880 sink->jclient = NULL;
881 sink->ports = NULL;
882 sink->port_count = 0;
883 sink->buffers = NULL;
884 sink->client_name = g_strdup (DEFAULT_PROP_CLIENT_NAME);
885 sink->transport = DEFAULT_PROP_TRANSPORT;
886 sink->low_latency = DEFAULT_PROP_LOW_LATENCY;
887 }
888
889 static void
gst_jack_audio_sink_dispose(GObject * object)890 gst_jack_audio_sink_dispose (GObject * object)
891 {
892 GstJackAudioSink *sink = GST_JACK_AUDIO_SINK (object);
893
894 gst_caps_replace (&sink->caps, NULL);
895
896 if (sink->client_name != NULL) {
897 g_free (sink->client_name);
898 sink->client_name = NULL;
899 }
900
901 if (sink->port_pattern != NULL) {
902 g_free (sink->port_pattern);
903 sink->port_pattern = NULL;
904 }
905
906 g_clear_pointer (&sink->port_names, g_free);
907
908 G_OBJECT_CLASS (parent_class)->dispose (object);
909 }
910
911 static void
gst_jack_audio_sink_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)912 gst_jack_audio_sink_set_property (GObject * object, guint prop_id,
913 const GValue * value, GParamSpec * pspec)
914 {
915 GstJackAudioSink *sink;
916
917 sink = GST_JACK_AUDIO_SINK (object);
918
919 switch (prop_id) {
920 case PROP_CLIENT_NAME:
921 g_free (sink->client_name);
922 sink->client_name = g_value_dup_string (value);
923 break;
924 case PROP_PORT_PATTERN:
925 g_free (sink->port_pattern);
926 sink->port_pattern = g_value_dup_string (value);
927 break;
928 case PROP_CONNECT:
929 sink->connect = g_value_get_enum (value);
930 break;
931 case PROP_SERVER:
932 g_free (sink->server);
933 sink->server = g_value_dup_string (value);
934 break;
935 case PROP_CLIENT:
936 if (GST_STATE (sink) == GST_STATE_NULL ||
937 GST_STATE (sink) == GST_STATE_READY) {
938 sink->jclient = g_value_get_boxed (value);
939 }
940 break;
941 case PROP_TRANSPORT:
942 sink->transport = g_value_get_flags (value);
943 break;
944 case PROP_LOW_LATENCY:
945 sink->low_latency = g_value_get_boolean (value);
946 break;
947 case PROP_PORT_NAMES:
948 g_free (sink->port_names);
949 sink->port_names = g_value_dup_string (value);
950 break;
951 default:
952 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
953 break;
954 }
955 }
956
957 static void
gst_jack_audio_sink_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)958 gst_jack_audio_sink_get_property (GObject * object, guint prop_id,
959 GValue * value, GParamSpec * pspec)
960 {
961 GstJackAudioSink *sink;
962
963 sink = GST_JACK_AUDIO_SINK (object);
964
965 switch (prop_id) {
966 case PROP_CLIENT_NAME:
967 g_value_set_string (value, sink->client_name);
968 break;
969 case PROP_PORT_PATTERN:
970 g_value_set_string (value, sink->port_pattern);
971 break;
972 case PROP_CONNECT:
973 g_value_set_enum (value, sink->connect);
974 break;
975 case PROP_SERVER:
976 g_value_set_string (value, sink->server);
977 break;
978 case PROP_CLIENT:
979 g_value_set_boxed (value, sink->jclient);
980 break;
981 case PROP_TRANSPORT:
982 g_value_set_flags (value, sink->transport);
983 break;
984 case PROP_LOW_LATENCY:
985 g_value_set_boolean (value, sink->low_latency);
986 break;
987 case PROP_PORT_NAMES:
988 g_value_set_string (value, sink->port_names);
989 break;
990 default:
991 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
992 break;
993 }
994 }
995
996 static GstCaps *
gst_jack_audio_sink_getcaps(GstBaseSink * bsink,GstCaps * filter)997 gst_jack_audio_sink_getcaps (GstBaseSink * bsink, GstCaps * filter)
998 {
999 GstJackAudioSink *sink = GST_JACK_AUDIO_SINK (bsink);
1000 const char **ports;
1001 gint min, max;
1002 gint rate;
1003 jack_client_t *client;
1004
1005 if (sink->client == NULL)
1006 goto no_client;
1007
1008 if (sink->connect == GST_JACK_CONNECT_EXPLICIT && !sink->port_names)
1009 goto no_port_names;
1010
1011 client = gst_jack_audio_client_get_client (sink->client);
1012
1013 if (sink->connect == GST_JACK_CONNECT_AUTO ||
1014 sink->connect == GST_JACK_CONNECT_EXPLICIT) {
1015 max = 0;
1016
1017 if (sink->port_names) {
1018 gchar **user_ports =
1019 gst_jack_audio_client_get_port_names_from_string (client,
1020 sink->port_names, JackPortIsInput);
1021
1022 if (user_ports) {
1023 max = g_strv_length (user_ports);
1024 } else {
1025 GST_ELEMENT_WARNING (sink, RESOURCE, NOT_FOUND,
1026 ("Invalid \"port-names\" was requested"),
1027 ("Requested \"port-names\" %s contains invalid name",
1028 sink->port_names));
1029 }
1030
1031 g_strfreev (user_ports);
1032 }
1033
1034 if (max > 0)
1035 goto found;
1036
1037 if (sink->connect == GST_JACK_CONNECT_EXPLICIT)
1038 goto no_port_names;
1039
1040 /* get a port count, this is the number of channels we can automatically
1041 * connect. */
1042 ports = jack_get_ports (client, NULL, NULL,
1043 JackPortIsPhysical | JackPortIsInput);
1044 if (ports != NULL) {
1045 for (; ports[max]; max++);
1046 jack_free (ports);
1047 } else
1048 max = 0;
1049 } else {
1050 /* we allow any number of pads, something else is going to connect the
1051 * pads. */
1052 max = G_MAXINT;
1053 }
1054
1055 found:
1056 if (sink->connect == GST_JACK_CONNECT_EXPLICIT) {
1057 min = max;
1058 } else {
1059 min = MIN (1, max);
1060 }
1061
1062 rate = jack_get_sample_rate (client);
1063
1064 GST_DEBUG_OBJECT (sink, "got %d-%d ports, samplerate: %d", min, max, rate);
1065
1066 if (!sink->caps) {
1067 sink->caps = gst_caps_new_simple ("audio/x-raw",
1068 "format", G_TYPE_STRING, GST_JACK_FORMAT_STR,
1069 "layout", G_TYPE_STRING, "interleaved", "rate", G_TYPE_INT, rate, NULL);
1070 if (min == max) {
1071 gst_caps_set_simple (sink->caps, "channels", G_TYPE_INT, min, NULL);
1072 } else {
1073 gst_caps_set_simple (sink->caps,
1074 "channels", GST_TYPE_INT_RANGE, min, max, NULL);
1075 }
1076 }
1077 GST_INFO_OBJECT (sink, "returning caps %" GST_PTR_FORMAT, sink->caps);
1078
1079 return gst_caps_ref (sink->caps);
1080
1081 /* ERRORS */
1082 no_client:
1083 {
1084 GST_DEBUG_OBJECT (sink, "device not open, using template caps");
1085 /* base class will get template caps for us when we return NULL */
1086 return NULL;
1087 }
1088 no_port_names:
1089 {
1090 GST_ELEMENT_ERROR (sink, RESOURCE, SETTINGS,
1091 ("User must provide valid port names"),
1092 ("\"port-names\" contains invalid name or NULL string"));
1093 return NULL;
1094 }
1095 }
1096
1097 static GstAudioRingBuffer *
gst_jack_audio_sink_create_ringbuffer(GstAudioBaseSink * sink)1098 gst_jack_audio_sink_create_ringbuffer (GstAudioBaseSink * sink)
1099 {
1100 GstAudioRingBuffer *buffer;
1101
1102 buffer = g_object_new (GST_TYPE_JACK_RING_BUFFER, NULL);
1103 GST_DEBUG_OBJECT (sink, "created ringbuffer @%p", buffer);
1104
1105 return buffer;
1106 }
1107