upload tizen1.0 source
[framework/multimedia/gst-plugins-good0.10.git] / ext / jack / gstjackaudiosink.c
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., 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
21
22 /**
23  * SECTION:element-jackaudiosink
24  * @see_also: #GstBaseAudioSink, #GstRingBuffer
25  *
26  * A Sink that outputs data to Jack ports.
27  * 
28  * It will create N Jack ports named out_&lt;name&gt;_&lt;num&gt; where 
29  * &lt;name&gt; is the element name and &lt;num&gt; 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 audiotestsrc ! jackaudiosink
52  * ]| Play a sine wave to using jack.
53  * </refsect2>
54  *
55  * Last reviewed on 2006-11-30 (0.10.4)
56  */
57
58 #ifdef HAVE_CONFIG_H
59 #include "config.h"
60 #endif
61
62 #include <gst/gst-i18n-plugin.h>
63 #include <stdlib.h>
64 #include <string.h>
65
66 #include "gstjackaudiosink.h"
67 #include "gstjackringbuffer.h"
68
69 GST_DEBUG_CATEGORY_STATIC (gst_jack_audio_sink_debug);
70 #define GST_CAT_DEFAULT gst_jack_audio_sink_debug
71
72 static gboolean
73 gst_jack_audio_sink_allocate_channels (GstJackAudioSink * sink, gint channels)
74 {
75   jack_client_t *client;
76
77   client = gst_jack_audio_client_get_client (sink->client);
78
79   /* remove ports we don't need */
80   while (sink->port_count > channels) {
81     jack_port_unregister (client, sink->ports[--sink->port_count]);
82   }
83
84   /* alloc enough output ports */
85   sink->ports = g_realloc (sink->ports, sizeof (jack_port_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
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 }
127
128 /* ringbuffer abstract base class */
129 static GType
130 gst_jack_ring_buffer_get_type (void)
131 {
132   static volatile gsize ringbuffer_type = 0;
133
134   if (g_once_init_enter (&ringbuffer_type)) {
135     static const GTypeInfo ringbuffer_info = {
136       sizeof (GstJackRingBufferClass),
137       NULL,
138       NULL,
139       (GClassInitFunc) gst_jack_ring_buffer_class_init,
140       NULL,
141       NULL,
142       sizeof (GstJackRingBuffer),
143       0,
144       (GInstanceInitFunc) gst_jack_ring_buffer_init,
145       NULL
146     };
147     GType tmp = g_type_register_static (GST_TYPE_RING_BUFFER,
148         "GstJackAudioSinkRingBuffer", &ringbuffer_info, 0);
149     g_once_init_leave (&ringbuffer_type, tmp);
150   }
151
152   return (GType) ringbuffer_type;
153 }
154
155 static void
156 gst_jack_ring_buffer_class_init (GstJackRingBufferClass * klass)
157 {
158   GstRingBufferClass *gstringbuffer_class;
159
160   gstringbuffer_class = (GstRingBufferClass *) klass;
161
162   ring_parent_class = g_type_class_peek_parent (klass);
163
164   gstringbuffer_class->open_device =
165       GST_DEBUG_FUNCPTR (gst_jack_ring_buffer_open_device);
166   gstringbuffer_class->close_device =
167       GST_DEBUG_FUNCPTR (gst_jack_ring_buffer_close_device);
168   gstringbuffer_class->acquire =
169       GST_DEBUG_FUNCPTR (gst_jack_ring_buffer_acquire);
170   gstringbuffer_class->release =
171       GST_DEBUG_FUNCPTR (gst_jack_ring_buffer_release);
172   gstringbuffer_class->start = GST_DEBUG_FUNCPTR (gst_jack_ring_buffer_start);
173   gstringbuffer_class->pause = GST_DEBUG_FUNCPTR (gst_jack_ring_buffer_pause);
174   gstringbuffer_class->resume = GST_DEBUG_FUNCPTR (gst_jack_ring_buffer_start);
175   gstringbuffer_class->stop = GST_DEBUG_FUNCPTR (gst_jack_ring_buffer_stop);
176
177   gstringbuffer_class->delay = GST_DEBUG_FUNCPTR (gst_jack_ring_buffer_delay);
178 }
179
180 /* this is the callback of jack. This should RT-safe.
181  */
182 static int
183 jack_process_cb (jack_nframes_t nframes, void *arg)
184 {
185   GstJackAudioSink *sink;
186   GstRingBuffer *buf;
187   gint readseg, len;
188   guint8 *readptr;
189   gint i, j, flen, channels;
190   sample_t **buffers, *data;
191
192   buf = GST_RING_BUFFER_CAST (arg);
193   sink = GST_JACK_AUDIO_SINK (GST_OBJECT_PARENT (buf));
194
195   channels = buf->spec.channels;
196
197   /* alloc pointers to samples */
198   buffers = g_alloca (sizeof (sample_t *) * channels);
199
200   /* get target buffers */
201   for (i = 0; i < channels; i++) {
202     buffers[i] = (sample_t *) jack_port_get_buffer (sink->ports[i], nframes);
203   }
204
205   if (gst_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         buffers[j][i] = *data++;
221       }
222     }
223
224     /* clear written samples in the ringbuffer */
225     gst_ring_buffer_clear (buf, readseg);
226
227     /* we wrote one segment */
228     gst_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 (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
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
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
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
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
321 gst_jack_ring_buffer_open_device (GstRingBuffer * 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   name = g_get_application_name ();
332   if (!name)
333     name = "GStreamer";
334
335   sink->client = gst_jack_audio_client_new (name, sink->server,
336       sink->jclient,
337       GST_JACK_CLIENT_SINK,
338       jack_shutdown_cb,
339       jack_process_cb, jack_buffer_size_cb, jack_sample_rate_cb, buf, &status);
340   if (sink->client == NULL)
341     goto could_not_open;
342
343   GST_DEBUG_OBJECT (sink, "opened");
344
345   return TRUE;
346
347   /* ERRORS */
348 could_not_open:
349   {
350     if (status & JackServerFailed) {
351       GST_ELEMENT_ERROR (sink, RESOURCE, NOT_FOUND,
352           (_("Jack server not found")),
353           ("Cannot connect to the Jack server (status %d)", status));
354     } else {
355       GST_ELEMENT_ERROR (sink, RESOURCE, OPEN_WRITE,
356           (NULL), ("Jack client open error (status %d)", status));
357     }
358     return FALSE;
359   }
360 }
361
362 /* close the connection with the server
363  */
364 static gboolean
365 gst_jack_ring_buffer_close_device (GstRingBuffer * buf)
366 {
367   GstJackAudioSink *sink;
368
369   sink = GST_JACK_AUDIO_SINK (GST_OBJECT_PARENT (buf));
370
371   GST_DEBUG_OBJECT (sink, "close");
372
373   gst_jack_audio_sink_free_channels (sink);
374   gst_jack_audio_client_free (sink->client);
375   sink->client = NULL;
376
377   return TRUE;
378 }
379
380 /* allocate a buffer and setup resources to process the audio samples of
381  * the format as specified in @spec.
382  *
383  * We allocate N jack ports, one for each channel. If we are asked to
384  * automatically make a connection with physical ports, we connect as many
385  * ports as there are physical ports, leaving leftover ports unconnected.
386  *
387  * It is assumed that samplerate and number of channels are acceptable since our
388  * getcaps method will always provide correct values. If unacceptable caps are
389  * received for some reason, we fail here.
390  */
391 static gboolean
392 gst_jack_ring_buffer_acquire (GstRingBuffer * buf, GstRingBufferSpec * spec)
393 {
394   GstJackAudioSink *sink;
395   GstJackRingBuffer *abuf;
396   const char **ports;
397   gint sample_rate, buffer_size;
398   gint i, channels, res;
399   jack_client_t *client;
400
401   sink = GST_JACK_AUDIO_SINK (GST_OBJECT_PARENT (buf));
402   abuf = GST_JACK_RING_BUFFER_CAST (buf);
403
404   GST_DEBUG_OBJECT (sink, "acquire");
405
406   client = gst_jack_audio_client_get_client (sink->client);
407
408   /* sample rate must be that of the server */
409   sample_rate = jack_get_sample_rate (client);
410   if (sample_rate != spec->rate)
411     goto wrong_samplerate;
412
413   channels = spec->channels;
414
415   if (!gst_jack_audio_sink_allocate_channels (sink, channels))
416     goto out_of_ports;
417
418   buffer_size = jack_get_buffer_size (client);
419
420   /* the segment size in bytes, this is large enough to hold a buffer of 32bit floats
421    * for all channels  */
422   spec->segsize = buffer_size * sizeof (gfloat) * channels;
423   spec->latency_time = gst_util_uint64_scale (spec->segsize,
424       (GST_SECOND / GST_USECOND), spec->rate * spec->bytes_per_sample);
425   /* segtotal based on buffer-time latency */
426   spec->segtotal = spec->buffer_time / spec->latency_time;
427   if (spec->segtotal < 2) {
428     spec->segtotal = 2;
429     spec->buffer_time = spec->latency_time * spec->segtotal;
430   }
431
432   GST_DEBUG_OBJECT (sink, "buffer time: %" G_GINT64_FORMAT " usec",
433       spec->buffer_time);
434   GST_DEBUG_OBJECT (sink, "latency time: %" G_GINT64_FORMAT " usec",
435       spec->latency_time);
436   GST_DEBUG_OBJECT (sink, "buffer_size %d, segsize %d, segtotal %d",
437       buffer_size, spec->segsize, spec->segtotal);
438
439   /* allocate the ringbuffer memory now */
440   buf->data = gst_buffer_new_and_alloc (spec->segtotal * spec->segsize);
441   memset (GST_BUFFER_DATA (buf->data), 0, GST_BUFFER_SIZE (buf->data));
442
443   if ((res = gst_jack_audio_client_set_active (sink->client, TRUE)))
444     goto could_not_activate;
445
446   /* if we need to automatically connect the ports, do so now. We must do this
447    * after activating the client. */
448   if (sink->connect == GST_JACK_CONNECT_AUTO
449       || sink->connect == GST_JACK_CONNECT_AUTO_FORCED) {
450     /* find all the physical input ports. A physical input port is a port
451      * associated with a hardware device. Someone needs connect to a physical
452      * port in order to hear something. */
453     ports = jack_get_ports (client, NULL, NULL,
454         JackPortIsPhysical | JackPortIsInput);
455     if (ports == NULL) {
456       /* no ports? fine then we don't do anything except for posting a warning
457        * message. */
458       GST_ELEMENT_WARNING (sink, RESOURCE, NOT_FOUND, (NULL),
459           ("No physical input ports found, leaving ports unconnected"));
460       goto done;
461     }
462
463     for (i = 0; i < channels; i++) {
464       /* stop when all input ports are exhausted */
465       if (ports[i] == NULL) {
466         /* post a warning that we could not connect all ports */
467         GST_ELEMENT_WARNING (sink, RESOURCE, NOT_FOUND, (NULL),
468             ("No more physical ports, leaving some ports unconnected"));
469         break;
470       }
471       GST_DEBUG_OBJECT (sink, "try connecting to %s",
472           jack_port_name (sink->ports[i]));
473       /* connect the port to a physical port */
474       res = jack_connect (client, jack_port_name (sink->ports[i]), ports[i]);
475       if (res != 0 && res != EEXIST)
476         goto cannot_connect;
477     }
478     free (ports);
479   }
480 done:
481
482   abuf->sample_rate = sample_rate;
483   abuf->buffer_size = buffer_size;
484   abuf->channels = spec->channels;
485
486   return TRUE;
487
488   /* ERRORS */
489 wrong_samplerate:
490   {
491     GST_ELEMENT_ERROR (sink, RESOURCE, SETTINGS, (NULL),
492         ("Wrong samplerate, server is running at %d and we received %d",
493             sample_rate, spec->rate));
494     return FALSE;
495   }
496 out_of_ports:
497   {
498     GST_ELEMENT_ERROR (sink, RESOURCE, SETTINGS, (NULL),
499         ("Cannot allocate more Jack ports"));
500     return FALSE;
501   }
502 could_not_activate:
503   {
504     GST_ELEMENT_ERROR (sink, RESOURCE, SETTINGS, (NULL),
505         ("Could not activate client (%d:%s)", res, g_strerror (res)));
506     return FALSE;
507   }
508 cannot_connect:
509   {
510     GST_ELEMENT_ERROR (sink, RESOURCE, SETTINGS, (NULL),
511         ("Could not connect output ports to physical ports (%d:%s)",
512             res, g_strerror (res)));
513     free (ports);
514     return FALSE;
515   }
516 }
517
518 /* function is called with LOCK */
519 static gboolean
520 gst_jack_ring_buffer_release (GstRingBuffer * buf)
521 {
522   GstJackAudioSink *sink;
523   GstJackRingBuffer *abuf;
524   gint res;
525
526   abuf = GST_JACK_RING_BUFFER_CAST (buf);
527   sink = GST_JACK_AUDIO_SINK (GST_OBJECT_PARENT (buf));
528
529   GST_DEBUG_OBJECT (sink, "release");
530
531   if ((res = gst_jack_audio_client_set_active (sink->client, FALSE))) {
532     /* we only warn, this means the server is probably shut down and the client
533      * is gone anyway. */
534     GST_ELEMENT_WARNING (sink, RESOURCE, CLOSE, (NULL),
535         ("Could not deactivate Jack client (%d)", res));
536   }
537
538   abuf->channels = -1;
539   abuf->buffer_size = -1;
540   abuf->sample_rate = -1;
541
542   /* free the buffer */
543   gst_buffer_unref (buf->data);
544   buf->data = NULL;
545
546   return TRUE;
547 }
548
549 static gboolean
550 gst_jack_ring_buffer_start (GstRingBuffer * buf)
551 {
552   GstJackAudioSink *sink;
553
554   sink = GST_JACK_AUDIO_SINK (GST_OBJECT_PARENT (buf));
555
556   GST_DEBUG_OBJECT (sink, "start");
557
558   return TRUE;
559 }
560
561 static gboolean
562 gst_jack_ring_buffer_pause (GstRingBuffer * buf)
563 {
564   GstJackAudioSink *sink;
565
566   sink = GST_JACK_AUDIO_SINK (GST_OBJECT_PARENT (buf));
567
568   GST_DEBUG_OBJECT (sink, "pause");
569
570   return TRUE;
571 }
572
573 static gboolean
574 gst_jack_ring_buffer_stop (GstRingBuffer * buf)
575 {
576   GstJackAudioSink *sink;
577
578   sink = GST_JACK_AUDIO_SINK (GST_OBJECT_PARENT (buf));
579
580   GST_DEBUG_OBJECT (sink, "stop");
581
582   return TRUE;
583 }
584
585 #if defined (HAVE_JACK_0_120_1) || defined(HAVE_JACK_1_9_7)
586 static guint
587 gst_jack_ring_buffer_delay (GstRingBuffer * buf)
588 {
589   GstJackAudioSink *sink;
590   guint i, res = 0;
591   jack_latency_range_t range;
592
593   sink = GST_JACK_AUDIO_SINK (GST_OBJECT_PARENT (buf));
594
595   for (i = 0; i < sink->port_count; i++) {
596     jack_port_get_latency_range (sink->ports[i], JackPlaybackLatency, &range);
597     if (range.max > res)
598       res = range.max;
599   }
600
601   GST_LOG_OBJECT (sink, "delay %u", res);
602
603   return res;
604 }
605 #else /* !(defined (HAVE_JACK_0_120_1) || defined(HAVE_JACK_1_9_7)) */
606 static guint
607 gst_jack_ring_buffer_delay (GstRingBuffer * buf)
608 {
609   GstJackAudioSink *sink;
610   guint i, res = 0;
611   guint latency;
612   jack_client_t *client;
613
614   sink = GST_JACK_AUDIO_SINK (GST_OBJECT_PARENT (buf));
615   client = gst_jack_audio_client_get_client (sink->client);
616
617   for (i = 0; i < sink->port_count; i++) {
618     latency = jack_port_get_total_latency (client, sink->ports[i]);
619     if (latency > res)
620       res = latency;
621   }
622
623   GST_LOG_OBJECT (sink, "delay %u", res);
624
625   return res;
626 }
627 #endif
628
629 static GstStaticPadTemplate jackaudiosink_sink_factory =
630 GST_STATIC_PAD_TEMPLATE ("sink",
631     GST_PAD_SINK,
632     GST_PAD_ALWAYS,
633     GST_STATIC_CAPS ("audio/x-raw-float, "
634         "endianness = (int) BYTE_ORDER, "
635         "width = (int) 32, "
636         "rate = (int) [ 1, MAX ], " "channels = (int) [ 1, MAX ]")
637     );
638
639 /* AudioSink signals and args */
640 enum
641 {
642   /* FILL ME */
643   SIGNAL_LAST
644 };
645
646 #define DEFAULT_PROP_CONNECT    GST_JACK_CONNECT_AUTO
647 #define DEFAULT_PROP_SERVER     NULL
648
649 enum
650 {
651   PROP_0,
652   PROP_CONNECT,
653   PROP_SERVER,
654   PROP_CLIENT,
655   PROP_LAST
656 };
657
658 #define _do_init(bla) \
659     GST_DEBUG_CATEGORY_INIT (gst_jack_audio_sink_debug, "jacksink", 0, "jacksink element");
660
661 GST_BOILERPLATE_FULL (GstJackAudioSink, gst_jack_audio_sink, GstBaseAudioSink,
662     GST_TYPE_BASE_AUDIO_SINK, _do_init);
663
664 static void gst_jack_audio_sink_dispose (GObject * object);
665 static void gst_jack_audio_sink_set_property (GObject * object, guint prop_id,
666     const GValue * value, GParamSpec * pspec);
667 static void gst_jack_audio_sink_get_property (GObject * object, guint prop_id,
668     GValue * value, GParamSpec * pspec);
669
670 static GstCaps *gst_jack_audio_sink_getcaps (GstBaseSink * bsink);
671 static GstRingBuffer *gst_jack_audio_sink_create_ringbuffer (GstBaseAudioSink *
672     sink);
673
674 static void
675 gst_jack_audio_sink_base_init (gpointer g_class)
676 {
677   GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
678
679   gst_element_class_set_details_simple (element_class, "Audio Sink (Jack)",
680       "Sink/Audio", "Output audio to a JACK server",
681       "Wim Taymans <wim.taymans@gmail.com>");
682
683   gst_element_class_add_pad_template (element_class,
684       gst_static_pad_template_get (&jackaudiosink_sink_factory));
685 }
686
687 static void
688 gst_jack_audio_sink_class_init (GstJackAudioSinkClass * klass)
689 {
690   GObjectClass *gobject_class;
691   GstBaseSinkClass *gstbasesink_class;
692   GstBaseAudioSinkClass *gstbaseaudiosink_class;
693
694   gobject_class = (GObjectClass *) klass;
695   gstbasesink_class = (GstBaseSinkClass *) klass;
696   gstbaseaudiosink_class = (GstBaseAudioSinkClass *) klass;
697
698   gobject_class->dispose = gst_jack_audio_sink_dispose;
699   gobject_class->get_property = gst_jack_audio_sink_get_property;
700   gobject_class->set_property = gst_jack_audio_sink_set_property;
701
702   g_object_class_install_property (gobject_class, PROP_CONNECT,
703       g_param_spec_enum ("connect", "Connect",
704           "Specify how the output ports will be connected",
705           GST_TYPE_JACK_CONNECT, DEFAULT_PROP_CONNECT,
706           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
707
708   g_object_class_install_property (gobject_class, PROP_SERVER,
709       g_param_spec_string ("server", "Server",
710           "The Jack server to connect to (NULL = default)",
711           DEFAULT_PROP_SERVER, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
712
713   g_object_class_install_property (gobject_class, PROP_CLIENT,
714       g_param_spec_boxed ("client", "JackClient", "Handle for jack client",
715           GST_TYPE_JACK_CLIENT,
716           GST_PARAM_MUTABLE_READY | G_PARAM_READWRITE |
717           G_PARAM_STATIC_STRINGS));
718
719   gstbasesink_class->get_caps = GST_DEBUG_FUNCPTR (gst_jack_audio_sink_getcaps);
720
721   gstbaseaudiosink_class->create_ringbuffer =
722       GST_DEBUG_FUNCPTR (gst_jack_audio_sink_create_ringbuffer);
723
724   /* ref class from a thread-safe context to work around missing bit of
725    * thread-safety in GObject */
726   g_type_class_ref (GST_TYPE_JACK_RING_BUFFER);
727
728   gst_jack_audio_client_init ();
729 }
730
731 static void
732 gst_jack_audio_sink_init (GstJackAudioSink * sink,
733     GstJackAudioSinkClass * g_class)
734 {
735   sink->connect = DEFAULT_PROP_CONNECT;
736   sink->server = g_strdup (DEFAULT_PROP_SERVER);
737   sink->jclient = NULL;
738   sink->ports = NULL;
739   sink->port_count = 0;
740 }
741
742 static void
743 gst_jack_audio_sink_dispose (GObject * object)
744 {
745   GstJackAudioSink *sink = GST_JACK_AUDIO_SINK (object);
746
747   gst_caps_replace (&sink->caps, NULL);
748   G_OBJECT_CLASS (parent_class)->dispose (object);
749 }
750
751 static void
752 gst_jack_audio_sink_set_property (GObject * object, guint prop_id,
753     const GValue * value, GParamSpec * pspec)
754 {
755   GstJackAudioSink *sink;
756
757   sink = GST_JACK_AUDIO_SINK (object);
758
759   switch (prop_id) {
760     case PROP_CONNECT:
761       sink->connect = g_value_get_enum (value);
762       break;
763     case PROP_SERVER:
764       g_free (sink->server);
765       sink->server = g_value_dup_string (value);
766       break;
767     case PROP_CLIENT:
768       if (GST_STATE (sink) == GST_STATE_NULL ||
769           GST_STATE (sink) == GST_STATE_READY) {
770         sink->jclient = g_value_get_boxed (value);
771       }
772       break;
773     default:
774       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
775       break;
776   }
777 }
778
779 static void
780 gst_jack_audio_sink_get_property (GObject * object, guint prop_id,
781     GValue * value, GParamSpec * pspec)
782 {
783   GstJackAudioSink *sink;
784
785   sink = GST_JACK_AUDIO_SINK (object);
786
787   switch (prop_id) {
788     case PROP_CONNECT:
789       g_value_set_enum (value, sink->connect);
790       break;
791     case PROP_SERVER:
792       g_value_set_string (value, sink->server);
793       break;
794     case PROP_CLIENT:
795       g_value_set_boxed (value, sink->jclient);
796       break;
797     default:
798       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
799       break;
800   }
801 }
802
803 static GstCaps *
804 gst_jack_audio_sink_getcaps (GstBaseSink * bsink)
805 {
806   GstJackAudioSink *sink = GST_JACK_AUDIO_SINK (bsink);
807   const char **ports;
808   gint min, max;
809   gint rate;
810   jack_client_t *client;
811
812   if (sink->client == NULL)
813     goto no_client;
814
815   client = gst_jack_audio_client_get_client (sink->client);
816
817   if (sink->connect == GST_JACK_CONNECT_AUTO) {
818     /* get a port count, this is the number of channels we can automatically
819      * connect. */
820     ports = jack_get_ports (client, NULL, NULL,
821         JackPortIsPhysical | JackPortIsInput);
822     max = 0;
823     if (ports != NULL) {
824       for (; ports[max]; max++);
825       free (ports);
826     } else
827       max = 0;
828   } else {
829     /* we allow any number of pads, something else is going to connect the
830      * pads. */
831     max = G_MAXINT;
832   }
833   min = MIN (1, max);
834
835   rate = jack_get_sample_rate (client);
836
837   GST_DEBUG_OBJECT (sink, "got %d-%d ports, samplerate: %d", min, max, rate);
838
839   if (!sink->caps) {
840     sink->caps = gst_caps_new_simple ("audio/x-raw-float",
841         "endianness", G_TYPE_INT, G_BYTE_ORDER,
842         "width", G_TYPE_INT, 32,
843         "rate", G_TYPE_INT, rate,
844         "channels", GST_TYPE_INT_RANGE, min, max, NULL);
845   }
846   GST_INFO_OBJECT (sink, "returning caps %" GST_PTR_FORMAT, sink->caps);
847
848   return gst_caps_ref (sink->caps);
849
850   /* ERRORS */
851 no_client:
852   {
853     GST_DEBUG_OBJECT (sink, "device not open, using template caps");
854     /* base class will get template caps for us when we return NULL */
855     return NULL;
856   }
857 }
858
859 static GstRingBuffer *
860 gst_jack_audio_sink_create_ringbuffer (GstBaseAudioSink * sink)
861 {
862   GstRingBuffer *buffer;
863
864   buffer = g_object_new (GST_TYPE_JACK_RING_BUFFER, NULL);
865   GST_DEBUG_OBJECT (sink, "created ringbuffer @%p", buffer);
866
867   return buffer;
868 }