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 * @see_also: #GstAudioBaseSink, #GstAudioRingBuffer
25 *
26 * A Sink that outputs data to Jack ports.
27 *
28 * It will create N Jack ports named out_<name>_<num> where
29 * <name> is the element name and <num> is starting from 1.
30 * Each port corresponds to a gstreamer channel.
31 *
32 * The samplerate as exposed on the caps is always the same as the samplerate of
33 * the jack server.
34 *
35 * When the #GstJackAudioSink:connect property is set to auto, this element
36 * will try to connect each output port to a random physical jack input pin. In
37 * this mode, the sink will expose the number of physical channels on its pad
38 * caps.
39 *
40 * When the #GstJackAudioSink:connect property is set to none, the element will
41 * accept any number of input channels and will create (but not connect) an
42 * output port for each channel.
43 *
44 * The element will generate an error when the Jack server is shut down when it
45 * was PAUSED or PLAYING. This element does not support dynamic rate and buffer
46 * size changes at runtime.
47 *
48 * <refsect2>
49 * <title>Example launch line</title>
50 * |[
51 * gst-launch-1.0 audiotestsrc ! jackaudiosink
52 * ]| Play a sine wave to using jack.
53 * </refsect2>
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 volatile 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
182 /* this is the callback of jack. This should RT-safe.
183 */
184 static int
jack_process_cb(jack_nframes_t nframes,void * arg)185 jack_process_cb (jack_nframes_t nframes, void *arg)
186 {
187 GstJackAudioSink *sink;
188 GstAudioRingBuffer *buf;
189 gint readseg, len;
190 guint8 *readptr;
191 gint i, j, flen, channels;
192 sample_t *data;
193
194 buf = GST_AUDIO_RING_BUFFER_CAST (arg);
195 sink = GST_JACK_AUDIO_SINK (GST_OBJECT_PARENT (buf));
196
197 channels = GST_AUDIO_INFO_CHANNELS (&buf->spec.info);
198
199 /* get target buffers */
200 for (i = 0; i < channels; i++) {
201 sink->buffers[i] =
202 (sample_t *) jack_port_get_buffer (sink->ports[i], nframes);
203 }
204
205 if (gst_audio_ring_buffer_prepare_read (buf, &readseg, &readptr, &len)) {
206 flen = len / channels;
207
208 /* the number of samples must be exactly the segment size */
209 if (nframes * sizeof (sample_t) != flen)
210 goto wrong_size;
211
212 GST_DEBUG_OBJECT (sink, "copy %d frames: %p, %d bytes, %d channels",
213 nframes, readptr, flen, channels);
214 data = (sample_t *) readptr;
215
216 /* the samples in the ringbuffer have the channels interleaved, we need to
217 * deinterleave into the jack target buffers */
218 for (i = 0; i < nframes; i++) {
219 for (j = 0; j < channels; j++) {
220 sink->buffers[j][i] = *data++;
221 }
222 }
223
224 /* clear written samples in the ringbuffer */
225 gst_audio_ring_buffer_clear (buf, readseg);
226
227 /* we wrote one segment */
228 gst_audio_ring_buffer_advance (buf, 1);
229 } else {
230 GST_DEBUG_OBJECT (sink, "write %d frames silence", nframes);
231 /* We are not allowed to read from the ringbuffer, write silence to all
232 * jack output buffers */
233 for (i = 0; i < channels; i++) {
234 memset (sink->buffers[i], 0, nframes * sizeof (sample_t));
235 }
236 }
237 return 0;
238
239 /* ERRORS */
240 wrong_size:
241 {
242 GST_ERROR_OBJECT (sink, "nbytes (%d) != flen (%d)",
243 (gint) (nframes * sizeof (sample_t)), flen);
244 return 1;
245 }
246 }
247
248 /* we error out */
249 static int
jack_sample_rate_cb(jack_nframes_t nframes,void * arg)250 jack_sample_rate_cb (jack_nframes_t nframes, void *arg)
251 {
252 GstJackAudioSink *sink;
253 GstJackRingBuffer *abuf;
254
255 abuf = GST_JACK_RING_BUFFER_CAST (arg);
256 sink = GST_JACK_AUDIO_SINK (GST_OBJECT_PARENT (arg));
257
258 if (abuf->sample_rate != -1 && abuf->sample_rate != nframes)
259 goto not_supported;
260
261 return 0;
262
263 /* ERRORS */
264 not_supported:
265 {
266 GST_ELEMENT_ERROR (sink, RESOURCE, SETTINGS,
267 (NULL), ("Jack changed the sample rate, which is not supported"));
268 return 1;
269 }
270 }
271
272 /* we error out */
273 static int
jack_buffer_size_cb(jack_nframes_t nframes,void * arg)274 jack_buffer_size_cb (jack_nframes_t nframes, void *arg)
275 {
276 GstJackAudioSink *sink;
277 GstJackRingBuffer *abuf;
278
279 abuf = GST_JACK_RING_BUFFER_CAST (arg);
280 sink = GST_JACK_AUDIO_SINK (GST_OBJECT_PARENT (arg));
281
282 if (abuf->buffer_size != -1 && abuf->buffer_size != nframes)
283 goto not_supported;
284
285 return 0;
286
287 /* ERRORS */
288 not_supported:
289 {
290 GST_ELEMENT_ERROR (sink, RESOURCE, SETTINGS,
291 (NULL), ("Jack changed the buffer size, which is not supported"));
292 return 1;
293 }
294 }
295
296 static void
jack_shutdown_cb(void * arg)297 jack_shutdown_cb (void *arg)
298 {
299 GstJackAudioSink *sink;
300
301 sink = GST_JACK_AUDIO_SINK (GST_OBJECT_PARENT (arg));
302
303 GST_DEBUG_OBJECT (sink, "shutdown");
304
305 GST_ELEMENT_ERROR (sink, RESOURCE, NOT_FOUND,
306 (NULL), ("Jack server shutdown"));
307 }
308
309 static void
gst_jack_ring_buffer_init(GstJackRingBuffer * buf,GstJackRingBufferClass * g_class)310 gst_jack_ring_buffer_init (GstJackRingBuffer * buf,
311 GstJackRingBufferClass * g_class)
312 {
313 buf->channels = -1;
314 buf->buffer_size = -1;
315 buf->sample_rate = -1;
316 }
317
318 /* the _open_device method should make a connection with the server
319 */
320 static gboolean
gst_jack_ring_buffer_open_device(GstAudioRingBuffer * buf)321 gst_jack_ring_buffer_open_device (GstAudioRingBuffer * buf)
322 {
323 GstJackAudioSink *sink;
324 jack_status_t status = 0;
325 const gchar *name;
326
327 sink = GST_JACK_AUDIO_SINK (GST_OBJECT_PARENT (buf));
328
329 GST_DEBUG_OBJECT (sink, "open");
330
331 if (sink->client_name) {
332 name = sink->client_name;
333 } else {
334 name = g_get_application_name ();
335 }
336 if (!name)
337 name = "GStreamer";
338
339 sink->client = gst_jack_audio_client_new (name, sink->server,
340 sink->jclient,
341 GST_JACK_CLIENT_SINK,
342 jack_shutdown_cb,
343 jack_process_cb, jack_buffer_size_cb, jack_sample_rate_cb, buf, &status);
344 if (sink->client == NULL)
345 goto could_not_open;
346
347 GST_DEBUG_OBJECT (sink, "opened");
348
349 return TRUE;
350
351 /* ERRORS */
352 could_not_open:
353 {
354 if (status & JackServerFailed) {
355 GST_ELEMENT_ERROR (sink, RESOURCE, NOT_FOUND,
356 (_("Jack server not found")),
357 ("Cannot connect to the Jack server (status %d)", status));
358 } else {
359 GST_ELEMENT_ERROR (sink, RESOURCE, OPEN_WRITE,
360 (NULL), ("Jack client open error (status %d)", status));
361 }
362 return FALSE;
363 }
364 }
365
366 /* close the connection with the server
367 */
368 static gboolean
gst_jack_ring_buffer_close_device(GstAudioRingBuffer * buf)369 gst_jack_ring_buffer_close_device (GstAudioRingBuffer * buf)
370 {
371 GstJackAudioSink *sink;
372
373 sink = GST_JACK_AUDIO_SINK (GST_OBJECT_PARENT (buf));
374
375 GST_DEBUG_OBJECT (sink, "close");
376
377 gst_jack_audio_sink_free_channels (sink);
378 gst_jack_audio_client_free (sink->client);
379 sink->client = NULL;
380
381 return TRUE;
382 }
383
384 /* allocate a buffer and setup resources to process the audio samples of
385 * the format as specified in @spec.
386 *
387 * We allocate N jack ports, one for each channel. If we are asked to
388 * automatically make a connection with physical ports, we connect as many
389 * ports as there are physical ports, leaving leftover ports unconnected.
390 *
391 * It is assumed that samplerate and number of channels are acceptable since our
392 * getcaps method will always provide correct values. If unacceptable caps are
393 * received for some reason, we fail here.
394 */
395 static gboolean
gst_jack_ring_buffer_acquire(GstAudioRingBuffer * buf,GstAudioRingBufferSpec * spec)396 gst_jack_ring_buffer_acquire (GstAudioRingBuffer * buf,
397 GstAudioRingBufferSpec * spec)
398 {
399 GstJackAudioSink *sink;
400 GstJackRingBuffer *abuf;
401 const char **ports;
402 gint sample_rate, buffer_size;
403 gint i, rate, bpf, channels, res;
404 jack_client_t *client;
405
406 sink = GST_JACK_AUDIO_SINK (GST_OBJECT_PARENT (buf));
407 abuf = GST_JACK_RING_BUFFER_CAST (buf);
408
409 GST_DEBUG_OBJECT (sink, "acquire");
410
411 client = gst_jack_audio_client_get_client (sink->client);
412
413 rate = GST_AUDIO_INFO_RATE (&spec->info);
414
415 /* sample rate must be that of the server */
416 sample_rate = jack_get_sample_rate (client);
417 if (sample_rate != rate)
418 goto wrong_samplerate;
419
420 channels = GST_AUDIO_INFO_CHANNELS (&spec->info);
421 bpf = GST_AUDIO_INFO_BPF (&spec->info);
422
423 if (!gst_jack_audio_sink_allocate_channels (sink, channels))
424 goto out_of_ports;
425
426 buffer_size = jack_get_buffer_size (client);
427
428 /* the segment size in bytes, this is large enough to hold a buffer of 32bit floats
429 * for all channels */
430 spec->segsize = buffer_size * sizeof (gfloat) * channels;
431 spec->latency_time = gst_util_uint64_scale (spec->segsize,
432 (GST_SECOND / GST_USECOND), rate * bpf);
433 /* segtotal based on buffer-time latency */
434 spec->segtotal = spec->buffer_time / spec->latency_time;
435 if (spec->segtotal < 2) {
436 spec->segtotal = 2;
437 spec->buffer_time = spec->latency_time * spec->segtotal;
438 }
439
440 GST_DEBUG_OBJECT (sink, "buffer time: %" G_GINT64_FORMAT " usec",
441 spec->buffer_time);
442 GST_DEBUG_OBJECT (sink, "latency time: %" G_GINT64_FORMAT " usec",
443 spec->latency_time);
444 GST_DEBUG_OBJECT (sink, "buffer_size %d, segsize %d, segtotal %d",
445 buffer_size, spec->segsize, spec->segtotal);
446
447 /* allocate the ringbuffer memory now */
448 buf->size = spec->segtotal * spec->segsize;
449 buf->memory = g_malloc0 (buf->size);
450
451 if ((res = gst_jack_audio_client_set_active (sink->client, TRUE)))
452 goto could_not_activate;
453
454 /* if we need to automatically connect the ports, do so now. We must do this
455 * after activating the client. */
456 if (sink->connect == GST_JACK_CONNECT_AUTO
457 || sink->connect == GST_JACK_CONNECT_AUTO_FORCED) {
458 /* find all the physical input ports. A physical input port is a port
459 * associated with a hardware device. Someone needs connect to a physical
460 * port in order to hear something. */
461 if (sink->port_pattern == NULL) {
462 ports = jack_get_ports (client, NULL, NULL,
463 JackPortIsPhysical | JackPortIsInput);
464 } else {
465 ports = jack_get_ports (client, sink->port_pattern, NULL,
466 JackPortIsInput);
467 }
468 if (ports == NULL) {
469 /* no ports? fine then we don't do anything except for posting a warning
470 * message. */
471 GST_ELEMENT_WARNING (sink, RESOURCE, NOT_FOUND, (NULL),
472 ("No physical input ports found, leaving ports unconnected"));
473 goto done;
474 }
475
476 for (i = 0; i < channels; i++) {
477 /* stop when all input ports are exhausted */
478 if (ports[i] == NULL) {
479 /* post a warning that we could not connect all ports */
480 GST_ELEMENT_WARNING (sink, RESOURCE, NOT_FOUND, (NULL),
481 ("No more physical ports, leaving some ports unconnected"));
482 break;
483 }
484 GST_DEBUG_OBJECT (sink, "try connecting to %s",
485 jack_port_name (sink->ports[i]));
486 /* connect the port to a physical port */
487 res = jack_connect (client, jack_port_name (sink->ports[i]), ports[i]);
488 if (res != 0 && res != EEXIST)
489 goto cannot_connect;
490 }
491 free (ports);
492 }
493 done:
494
495 abuf->sample_rate = sample_rate;
496 abuf->buffer_size = buffer_size;
497 abuf->channels = channels;
498
499 return TRUE;
500
501 /* ERRORS */
502 wrong_samplerate:
503 {
504 GST_ELEMENT_ERROR (sink, RESOURCE, SETTINGS, (NULL),
505 ("Wrong samplerate, server is running at %d and we received %d",
506 sample_rate, rate));
507 return FALSE;
508 }
509 out_of_ports:
510 {
511 GST_ELEMENT_ERROR (sink, RESOURCE, SETTINGS, (NULL),
512 ("Cannot allocate more Jack ports"));
513 return FALSE;
514 }
515 could_not_activate:
516 {
517 GST_ELEMENT_ERROR (sink, RESOURCE, SETTINGS, (NULL),
518 ("Could not activate client (%d:%s)", res, g_strerror (res)));
519 return FALSE;
520 }
521 cannot_connect:
522 {
523 GST_ELEMENT_ERROR (sink, RESOURCE, SETTINGS, (NULL),
524 ("Could not connect output ports to physical ports (%d:%s)",
525 res, g_strerror (res)));
526 free (ports);
527 return FALSE;
528 }
529 }
530
531 /* function is called with LOCK */
532 static gboolean
gst_jack_ring_buffer_release(GstAudioRingBuffer * buf)533 gst_jack_ring_buffer_release (GstAudioRingBuffer * buf)
534 {
535 GstJackAudioSink *sink;
536 GstJackRingBuffer *abuf;
537 gint res;
538
539 abuf = GST_JACK_RING_BUFFER_CAST (buf);
540 sink = GST_JACK_AUDIO_SINK (GST_OBJECT_PARENT (buf));
541
542 GST_DEBUG_OBJECT (sink, "release");
543
544 if ((res = gst_jack_audio_client_set_active (sink->client, FALSE))) {
545 /* we only warn, this means the server is probably shut down and the client
546 * is gone anyway. */
547 GST_ELEMENT_WARNING (sink, RESOURCE, CLOSE, (NULL),
548 ("Could not deactivate Jack client (%d)", res));
549 }
550
551 abuf->channels = -1;
552 abuf->buffer_size = -1;
553 abuf->sample_rate = -1;
554
555 /* free the buffer */
556 g_free (buf->memory);
557 buf->memory = NULL;
558
559 return TRUE;
560 }
561
562 static gboolean
gst_jack_ring_buffer_start(GstAudioRingBuffer * buf)563 gst_jack_ring_buffer_start (GstAudioRingBuffer * buf)
564 {
565 GstJackAudioSink *sink;
566
567 sink = GST_JACK_AUDIO_SINK (GST_OBJECT_PARENT (buf));
568
569 GST_DEBUG_OBJECT (sink, "start");
570
571 if (sink->transport & GST_JACK_TRANSPORT_MASTER) {
572 jack_client_t *client;
573
574 client = gst_jack_audio_client_get_client (sink->client);
575 jack_transport_start (client);
576 }
577
578 return TRUE;
579 }
580
581 static gboolean
gst_jack_ring_buffer_pause(GstAudioRingBuffer * buf)582 gst_jack_ring_buffer_pause (GstAudioRingBuffer * buf)
583 {
584 GstJackAudioSink *sink;
585
586 sink = GST_JACK_AUDIO_SINK (GST_OBJECT_PARENT (buf));
587
588 GST_DEBUG_OBJECT (sink, "pause");
589
590 if (sink->transport & GST_JACK_TRANSPORT_MASTER) {
591 jack_client_t *client;
592
593 client = gst_jack_audio_client_get_client (sink->client);
594 jack_transport_stop (client);
595 }
596
597 return TRUE;
598 }
599
600 static gboolean
gst_jack_ring_buffer_stop(GstAudioRingBuffer * buf)601 gst_jack_ring_buffer_stop (GstAudioRingBuffer * buf)
602 {
603 GstJackAudioSink *sink;
604
605 sink = GST_JACK_AUDIO_SINK (GST_OBJECT_PARENT (buf));
606
607 GST_DEBUG_OBJECT (sink, "stop");
608
609 if (sink->transport & GST_JACK_TRANSPORT_MASTER) {
610 jack_client_t *client;
611
612 client = gst_jack_audio_client_get_client (sink->client);
613 jack_transport_stop (client);
614 }
615
616 return TRUE;
617 }
618
619 #if defined (HAVE_JACK_0_120_1) || defined(HAVE_JACK_1_9_7)
620 static guint
gst_jack_ring_buffer_delay(GstAudioRingBuffer * buf)621 gst_jack_ring_buffer_delay (GstAudioRingBuffer * buf)
622 {
623 GstJackAudioSink *sink;
624 guint i, res = 0;
625 jack_latency_range_t range;
626
627 sink = GST_JACK_AUDIO_SINK (GST_OBJECT_PARENT (buf));
628
629 for (i = 0; i < sink->port_count; i++) {
630 jack_port_get_latency_range (sink->ports[i], JackPlaybackLatency, &range);
631 if (range.max > res)
632 res = range.max;
633 }
634
635 GST_LOG_OBJECT (sink, "delay %u", res);
636
637 return res;
638 }
639 #else /* !(defined (HAVE_JACK_0_120_1) || defined(HAVE_JACK_1_9_7)) */
640 static guint
gst_jack_ring_buffer_delay(GstAudioRingBuffer * buf)641 gst_jack_ring_buffer_delay (GstAudioRingBuffer * buf)
642 {
643 GstJackAudioSink *sink;
644 guint i, res = 0;
645 guint latency;
646 jack_client_t *client;
647
648 sink = GST_JACK_AUDIO_SINK (GST_OBJECT_PARENT (buf));
649 client = gst_jack_audio_client_get_client (sink->client);
650
651 for (i = 0; i < sink->port_count; i++) {
652 latency = jack_port_get_total_latency (client, sink->ports[i]);
653 if (latency > res)
654 res = latency;
655 }
656
657 GST_LOG_OBJECT (sink, "delay %u", res);
658
659 return res;
660 }
661 #endif
662
663 static GstStaticPadTemplate jackaudiosink_sink_factory =
664 GST_STATIC_PAD_TEMPLATE ("sink",
665 GST_PAD_SINK,
666 GST_PAD_ALWAYS,
667 GST_STATIC_CAPS ("audio/x-raw, "
668 "format = (string) " GST_JACK_FORMAT_STR ", "
669 "layout = (string) interleaved, "
670 "rate = (int) [ 1, MAX ], " "channels = (int) [ 1, MAX ]")
671 );
672
673 /* AudioSink signals and args */
674 enum
675 {
676 /* FILL ME */
677 SIGNAL_LAST
678 };
679
680 #define DEFAULT_PROP_CONNECT GST_JACK_CONNECT_AUTO
681 #define DEFAULT_PROP_SERVER NULL
682 #define DEFAULT_PROP_CLIENT_NAME NULL
683 #define DEFAULT_PROP_PORT_PATTERN NULL
684 #define DEFAULT_PROP_TRANSPORT GST_JACK_TRANSPORT_AUTONOMOUS
685
686 enum
687 {
688 PROP_0,
689 PROP_CONNECT,
690 PROP_SERVER,
691 PROP_CLIENT,
692 PROP_CLIENT_NAME,
693 PROP_PORT_PATTERN,
694 PROP_TRANSPORT,
695 PROP_LAST
696 };
697
698 #define gst_jack_audio_sink_parent_class parent_class
699 G_DEFINE_TYPE (GstJackAudioSink, gst_jack_audio_sink, GST_TYPE_AUDIO_BASE_SINK);
700
701 static void gst_jack_audio_sink_dispose (GObject * object);
702 static void gst_jack_audio_sink_set_property (GObject * object, guint prop_id,
703 const GValue * value, GParamSpec * pspec);
704 static void gst_jack_audio_sink_get_property (GObject * object, guint prop_id,
705 GValue * value, GParamSpec * pspec);
706
707 static GstCaps *gst_jack_audio_sink_getcaps (GstBaseSink * bsink,
708 GstCaps * filter);
709 static GstAudioRingBuffer
710 * gst_jack_audio_sink_create_ringbuffer (GstAudioBaseSink * sink);
711
712 static void
gst_jack_audio_sink_class_init(GstJackAudioSinkClass * klass)713 gst_jack_audio_sink_class_init (GstJackAudioSinkClass * klass)
714 {
715 GObjectClass *gobject_class;
716 GstElementClass *gstelement_class;
717 GstBaseSinkClass *gstbasesink_class;
718 GstAudioBaseSinkClass *gstaudiobasesink_class;
719
720 GST_DEBUG_CATEGORY_INIT (gst_jack_audio_sink_debug, "jacksink", 0,
721 "jacksink element");
722
723 gobject_class = (GObjectClass *) klass;
724 gstelement_class = (GstElementClass *) klass;
725 gstbasesink_class = (GstBaseSinkClass *) klass;
726 gstaudiobasesink_class = (GstAudioBaseSinkClass *) klass;
727
728 gobject_class->dispose = gst_jack_audio_sink_dispose;
729 gobject_class->get_property = gst_jack_audio_sink_get_property;
730 gobject_class->set_property = gst_jack_audio_sink_set_property;
731
732 g_object_class_install_property (gobject_class, PROP_CONNECT,
733 g_param_spec_enum ("connect", "Connect",
734 "Specify how the output ports will be connected",
735 GST_TYPE_JACK_CONNECT, DEFAULT_PROP_CONNECT,
736 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
737
738 g_object_class_install_property (gobject_class, PROP_SERVER,
739 g_param_spec_string ("server", "Server",
740 "The Jack server to connect to (NULL = default)",
741 DEFAULT_PROP_SERVER, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
742
743 /**
744 * GstJackAudioSink:client-name:
745 *
746 * The client name to use.
747 */
748 g_object_class_install_property (gobject_class, PROP_CLIENT_NAME,
749 g_param_spec_string ("client-name", "Client name",
750 "The client name of the Jack instance (NULL = default)",
751 DEFAULT_PROP_CLIENT_NAME,
752 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
753
754 g_object_class_install_property (gobject_class, PROP_CLIENT,
755 g_param_spec_boxed ("client", "JackClient", "Handle for jack client",
756 GST_TYPE_JACK_CLIENT,
757 GST_PARAM_MUTABLE_READY | G_PARAM_READWRITE |
758 G_PARAM_STATIC_STRINGS));
759
760 /**
761 * GstJackAudioSink:port-pattern
762 *
763 * autoconnect to ports matching pattern, when NULL connect to physical ports
764 *
765 * Since: 1.6
766 */
767 g_object_class_install_property (gobject_class, PROP_PORT_PATTERN,
768 g_param_spec_string ("port-pattern", "port pattern",
769 "A pattern to select which ports to connect to (NULL = first physical ports)",
770 DEFAULT_PROP_PORT_PATTERN,
771 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
772
773 /**
774 * GstJackAudioSink:transport:
775 *
776 * The jack transport behaviour for the client.
777 */
778 g_object_class_install_property (gobject_class, PROP_TRANSPORT,
779 g_param_spec_flags ("transport", "Transport mode",
780 "Jack transport behaviour of the client",
781 GST_TYPE_JACK_TRANSPORT, DEFAULT_PROP_TRANSPORT,
782 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
783
784 gst_element_class_set_static_metadata (gstelement_class, "Audio Sink (Jack)",
785 "Sink/Audio", "Output audio to a JACK server",
786 "Wim Taymans <wim.taymans@gmail.com>");
787
788 gst_element_class_add_static_pad_template (gstelement_class,
789 &jackaudiosink_sink_factory);
790
791 gstbasesink_class->get_caps = GST_DEBUG_FUNCPTR (gst_jack_audio_sink_getcaps);
792
793 gstaudiobasesink_class->create_ringbuffer =
794 GST_DEBUG_FUNCPTR (gst_jack_audio_sink_create_ringbuffer);
795
796 /* ref class from a thread-safe context to work around missing bit of
797 * thread-safety in GObject */
798 g_type_class_ref (GST_TYPE_JACK_RING_BUFFER);
799
800 gst_jack_audio_client_init ();
801 }
802
803 static void
gst_jack_audio_sink_init(GstJackAudioSink * sink)804 gst_jack_audio_sink_init (GstJackAudioSink * sink)
805 {
806 sink->connect = DEFAULT_PROP_CONNECT;
807 sink->server = g_strdup (DEFAULT_PROP_SERVER);
808 sink->jclient = NULL;
809 sink->ports = NULL;
810 sink->port_count = 0;
811 sink->buffers = NULL;
812 sink->client_name = g_strdup (DEFAULT_PROP_CLIENT_NAME);
813 sink->transport = DEFAULT_PROP_TRANSPORT;
814 }
815
816 static void
gst_jack_audio_sink_dispose(GObject * object)817 gst_jack_audio_sink_dispose (GObject * object)
818 {
819 GstJackAudioSink *sink = GST_JACK_AUDIO_SINK (object);
820
821 gst_caps_replace (&sink->caps, NULL);
822
823 if (sink->client_name != NULL) {
824 g_free (sink->client_name);
825 sink->client_name = NULL;
826 }
827
828 if (sink->port_pattern != NULL) {
829 g_free (sink->port_pattern);
830 sink->port_pattern = NULL;
831 }
832
833 G_OBJECT_CLASS (parent_class)->dispose (object);
834 }
835
836 static void
gst_jack_audio_sink_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)837 gst_jack_audio_sink_set_property (GObject * object, guint prop_id,
838 const GValue * value, GParamSpec * pspec)
839 {
840 GstJackAudioSink *sink;
841
842 sink = GST_JACK_AUDIO_SINK (object);
843
844 switch (prop_id) {
845 case PROP_CLIENT_NAME:
846 g_free (sink->client_name);
847 sink->client_name = g_value_dup_string (value);
848 break;
849 case PROP_PORT_PATTERN:
850 g_free (sink->port_pattern);
851 sink->port_pattern = g_value_dup_string (value);
852 break;
853 case PROP_CONNECT:
854 sink->connect = g_value_get_enum (value);
855 break;
856 case PROP_SERVER:
857 g_free (sink->server);
858 sink->server = g_value_dup_string (value);
859 break;
860 case PROP_CLIENT:
861 if (GST_STATE (sink) == GST_STATE_NULL ||
862 GST_STATE (sink) == GST_STATE_READY) {
863 sink->jclient = g_value_get_boxed (value);
864 }
865 break;
866 case PROP_TRANSPORT:
867 sink->transport = g_value_get_flags (value);
868 break;
869 default:
870 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
871 break;
872 }
873 }
874
875 static void
gst_jack_audio_sink_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)876 gst_jack_audio_sink_get_property (GObject * object, guint prop_id,
877 GValue * value, GParamSpec * pspec)
878 {
879 GstJackAudioSink *sink;
880
881 sink = GST_JACK_AUDIO_SINK (object);
882
883 switch (prop_id) {
884 case PROP_CLIENT_NAME:
885 g_value_set_string (value, sink->client_name);
886 break;
887 case PROP_PORT_PATTERN:
888 g_value_set_string (value, sink->port_pattern);
889 break;
890 case PROP_CONNECT:
891 g_value_set_enum (value, sink->connect);
892 break;
893 case PROP_SERVER:
894 g_value_set_string (value, sink->server);
895 break;
896 case PROP_CLIENT:
897 g_value_set_boxed (value, sink->jclient);
898 break;
899 case PROP_TRANSPORT:
900 g_value_set_flags (value, sink->transport);
901 break;
902 default:
903 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
904 break;
905 }
906 }
907
908 static GstCaps *
gst_jack_audio_sink_getcaps(GstBaseSink * bsink,GstCaps * filter)909 gst_jack_audio_sink_getcaps (GstBaseSink * bsink, GstCaps * filter)
910 {
911 GstJackAudioSink *sink = GST_JACK_AUDIO_SINK (bsink);
912 const char **ports;
913 gint min, max;
914 gint rate;
915 jack_client_t *client;
916
917 if (sink->client == NULL)
918 goto no_client;
919
920 client = gst_jack_audio_client_get_client (sink->client);
921
922 if (sink->connect == GST_JACK_CONNECT_AUTO) {
923 /* get a port count, this is the number of channels we can automatically
924 * connect. */
925 ports = jack_get_ports (client, NULL, NULL,
926 JackPortIsPhysical | JackPortIsInput);
927 max = 0;
928 if (ports != NULL) {
929 for (; ports[max]; max++);
930 free (ports);
931 } else
932 max = 0;
933 } else {
934 /* we allow any number of pads, something else is going to connect the
935 * pads. */
936 max = G_MAXINT;
937 }
938 min = MIN (1, max);
939
940 rate = jack_get_sample_rate (client);
941
942 GST_DEBUG_OBJECT (sink, "got %d-%d ports, samplerate: %d", min, max, rate);
943
944 if (!sink->caps) {
945 sink->caps = gst_caps_new_simple ("audio/x-raw",
946 "format", G_TYPE_STRING, GST_JACK_FORMAT_STR,
947 "layout", G_TYPE_STRING, "interleaved",
948 "rate", G_TYPE_INT, rate,
949 "channels", GST_TYPE_INT_RANGE, min, max, NULL);
950 }
951 GST_INFO_OBJECT (sink, "returning caps %" GST_PTR_FORMAT, sink->caps);
952
953 return gst_caps_ref (sink->caps);
954
955 /* ERRORS */
956 no_client:
957 {
958 GST_DEBUG_OBJECT (sink, "device not open, using template caps");
959 /* base class will get template caps for us when we return NULL */
960 return NULL;
961 }
962 }
963
964 static GstAudioRingBuffer *
gst_jack_audio_sink_create_ringbuffer(GstAudioBaseSink * sink)965 gst_jack_audio_sink_create_ringbuffer (GstAudioBaseSink * sink)
966 {
967 GstAudioRingBuffer *buffer;
968
969 buffer = g_object_new (GST_TYPE_JACK_RING_BUFFER, NULL);
970 GST_DEBUG_OBJECT (sink, "created ringbuffer @%p", buffer);
971
972 return buffer;
973 }
974