0e75f16d25977115af45e59cfb5d7aff92aa6477
[platform/upstream/gstreamer.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 #include <stdlib.h>
59 #include <string.h>
60
61 #include "gstjackaudiosink.h"
62 #include "gstjackringbuffer.h"
63
64 GST_DEBUG_CATEGORY_STATIC (gst_jack_audio_sink_debug);
65 #define GST_CAT_DEFAULT gst_jack_audio_sink_debug
66
67 static gboolean
68 gst_jack_audio_sink_allocate_channels (GstJackAudioSink * sink, gint channels)
69 {
70   jack_client_t *client;
71
72   client = gst_jack_audio_client_get_client (sink->client);
73
74   /* remove ports we don't need */
75   while (sink->port_count > channels) {
76     jack_port_unregister (client, sink->ports[--sink->port_count]);
77   }
78
79   /* alloc enough output ports */
80   sink->ports = g_realloc (sink->ports, sizeof (jack_port_t *) * channels);
81
82   /* create an output port for each channel */
83   while (sink->port_count < channels) {
84     gchar *name;
85
86     /* port names start from 1 and are local to the element */
87     name =
88         g_strdup_printf ("out_%s_%d", GST_ELEMENT_NAME (sink),
89         sink->port_count + 1);
90     sink->ports[sink->port_count] =
91         jack_port_register (client, name, JACK_DEFAULT_AUDIO_TYPE,
92         JackPortIsOutput, 0);
93     if (sink->ports[sink->port_count] == NULL)
94       return FALSE;
95
96     sink->port_count++;
97
98     g_free (name);
99   }
100   return TRUE;
101 }
102
103 static void
104 gst_jack_audio_sink_free_channels (GstJackAudioSink * sink)
105 {
106   gint res, i = 0;
107   jack_client_t *client;
108
109   client = gst_jack_audio_client_get_client (sink->client);
110
111   /* get rid of all ports */
112   while (sink->port_count) {
113     GST_LOG_OBJECT (sink, "unregister port %d", i);
114     if ((res = jack_port_unregister (client, sink->ports[i++]))) {
115       GST_DEBUG_OBJECT (sink, "unregister of port failed (%d)", res);
116     }
117     sink->port_count--;
118   }
119   g_free (sink->ports);
120   sink->ports = NULL;
121 }
122
123 /* ringbuffer abstract base class */
124 static GType
125 gst_jack_ring_buffer_get_type (void)
126 {
127   static GType ringbuffer_type = 0;
128
129   if (!ringbuffer_type) {
130     static const GTypeInfo ringbuffer_info = {
131       sizeof (GstJackRingBufferClass),
132       NULL,
133       NULL,
134       (GClassInitFunc) gst_jack_ring_buffer_class_init,
135       NULL,
136       NULL,
137       sizeof (GstJackRingBuffer),
138       0,
139       (GInstanceInitFunc) gst_jack_ring_buffer_init,
140       NULL
141     };
142
143     ringbuffer_type =
144         g_type_register_static (GST_TYPE_RING_BUFFER,
145         "GstJackAudioSinkRingBuffer", &ringbuffer_info, 0);
146   }
147   return ringbuffer_type;
148 }
149
150 static void
151 gst_jack_ring_buffer_class_init (GstJackRingBufferClass * klass)
152 {
153   GObjectClass *gobject_class;
154   GstObjectClass *gstobject_class;
155   GstRingBufferClass *gstringbuffer_class;
156
157   gobject_class = (GObjectClass *) klass;
158   gstobject_class = (GstObjectClass *) klass;
159   gstringbuffer_class = (GstRingBufferClass *) klass;
160
161   ring_parent_class = g_type_class_peek_parent (klass);
162
163   gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_jack_ring_buffer_dispose);
164   gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_jack_ring_buffer_finalize);
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
185 jack_process_cb (jack_nframes_t nframes, void *arg)
186 {
187   GstJackAudioSink *sink;
188   GstRingBuffer *buf;
189   GstJackRingBuffer *abuf;
190   gint readseg, len;
191   guint8 *readptr;
192   gint i, j, flen, channels;
193   sample_t **buffers, *data;
194
195   buf = GST_RING_BUFFER_CAST (arg);
196   abuf = GST_JACK_RING_BUFFER_CAST (arg);
197   sink = GST_JACK_AUDIO_SINK (GST_OBJECT_PARENT (buf));
198
199   channels = buf->spec.channels;
200
201   /* alloc pointers to samples */
202   buffers = g_alloca (sizeof (sample_t *) * channels);
203
204   /* get target buffers */
205   for (i = 0; i < channels; i++) {
206     buffers[i] = (sample_t *) jack_port_get_buffer (sink->ports[i], nframes);
207   }
208
209   if (gst_ring_buffer_prepare_read (buf, &readseg, &readptr, &len)) {
210     flen = len / channels;
211
212     /* the number of samples must be exactly the segment size */
213     if (nframes * sizeof (sample_t) != flen)
214       goto wrong_size;
215
216     GST_DEBUG_OBJECT (sink, "copy %d frames: %p, %d bytes, %d channels",
217         nframes, readptr, flen, channels);
218     data = (sample_t *) readptr;
219
220     /* the samples in the ringbuffer have the channels interleaved, we need to
221      * deinterleave into the jack target buffers */
222     for (i = 0; i < nframes; i++) {
223       for (j = 0; j < channels; j++) {
224         buffers[j][i] = *data++;
225       }
226     }
227
228     /* clear written samples in the ringbuffer */
229     gst_ring_buffer_clear (buf, readseg);
230
231     /* we wrote one segment */
232     gst_ring_buffer_advance (buf, 1);
233   } else {
234     GST_DEBUG_OBJECT (sink, "write %d frames silence", nframes);
235     /* We are not allowed to read from the ringbuffer, write silence to all
236      * jack output buffers */
237     for (i = 0; i < channels; i++) {
238       memset (buffers[i], 0, nframes * sizeof (sample_t));
239     }
240   }
241   return 0;
242
243   /* ERRORS */
244 wrong_size:
245   {
246     GST_ERROR_OBJECT (sink, "nbytes (%d) != flen (%d)",
247         (gint) (nframes * sizeof (sample_t)), flen);
248     return 1;
249   }
250 }
251
252 /* we error out */
253 static int
254 jack_sample_rate_cb (jack_nframes_t nframes, void *arg)
255 {
256   GstJackAudioSink *sink;
257   GstJackRingBuffer *abuf;
258
259   abuf = GST_JACK_RING_BUFFER_CAST (arg);
260   sink = GST_JACK_AUDIO_SINK (GST_OBJECT_PARENT (arg));
261
262   if (abuf->sample_rate != -1 && abuf->sample_rate != nframes)
263     goto not_supported;
264
265   return 0;
266
267   /* ERRORS */
268 not_supported:
269   {
270     GST_ELEMENT_ERROR (sink, RESOURCE, SETTINGS,
271         (NULL), ("Jack changed the sample rate, which is not supported"));
272     return 1;
273   }
274 }
275
276 /* we error out */
277 static int
278 jack_buffer_size_cb (jack_nframes_t nframes, void *arg)
279 {
280   GstJackAudioSink *sink;
281   GstJackRingBuffer *abuf;
282
283   abuf = GST_JACK_RING_BUFFER_CAST (arg);
284   sink = GST_JACK_AUDIO_SINK (GST_OBJECT_PARENT (arg));
285
286   if (abuf->buffer_size != -1 && abuf->buffer_size != nframes)
287     goto not_supported;
288
289   return 0;
290
291   /* ERRORS */
292 not_supported:
293   {
294     GST_ELEMENT_ERROR (sink, RESOURCE, SETTINGS,
295         (NULL), ("Jack changed the buffer size, which is not supported"));
296     return 1;
297   }
298 }
299
300 static void
301 jack_shutdown_cb (void *arg)
302 {
303   GstJackAudioSink *sink;
304
305   sink = GST_JACK_AUDIO_SINK (GST_OBJECT_PARENT (arg));
306
307   GST_DEBUG_OBJECT (sink, "shutdown");
308
309   GST_ELEMENT_ERROR (sink, RESOURCE, NOT_FOUND,
310       (NULL), ("Jack server shutdown"));
311 }
312
313 static void
314 gst_jack_ring_buffer_init (GstJackRingBuffer * buf,
315     GstJackRingBufferClass * g_class)
316 {
317   buf->channels = -1;
318   buf->buffer_size = -1;
319   buf->sample_rate = -1;
320 }
321
322 static void
323 gst_jack_ring_buffer_dispose (GObject * object)
324 {
325   G_OBJECT_CLASS (ring_parent_class)->dispose (object);
326 }
327
328 static void
329 gst_jack_ring_buffer_finalize (GObject * object)
330 {
331   GstJackRingBuffer *ringbuffer;
332
333   ringbuffer = GST_JACK_RING_BUFFER_CAST (object);
334
335   G_OBJECT_CLASS (ring_parent_class)->finalize (object);
336 }
337
338 /* the _open_device method should make a connection with the server
339  */
340 static gboolean
341 gst_jack_ring_buffer_open_device (GstRingBuffer * buf)
342 {
343   GstJackAudioSink *sink;
344   jack_status_t status = 0;
345   const gchar *name;
346
347   sink = GST_JACK_AUDIO_SINK (GST_OBJECT_PARENT (buf));
348
349   GST_DEBUG_OBJECT (sink, "open");
350
351   name = g_get_application_name ();
352   if (!name)
353     name = "GStreamer";
354
355   sink->client = gst_jack_audio_client_new (name, sink->server,
356       GST_JACK_CLIENT_SINK,
357       jack_shutdown_cb,
358       jack_process_cb, jack_buffer_size_cb, jack_sample_rate_cb, buf, &status);
359   if (sink->client == NULL)
360     goto could_not_open;
361
362   GST_DEBUG_OBJECT (sink, "opened");
363
364   return TRUE;
365
366   /* ERRORS */
367 could_not_open:
368   {
369     if (status & JackServerFailed) {
370       GST_ELEMENT_ERROR (sink, RESOURCE, NOT_FOUND,
371           (NULL), ("Cannot connect to the Jack server (status %d)", status));
372     } else {
373       GST_ELEMENT_ERROR (sink, RESOURCE, OPEN_WRITE,
374           (NULL), ("Jack client open error (status %d)", status));
375     }
376     return FALSE;
377   }
378 }
379
380 /* close the connection with the server
381  */
382 static gboolean
383 gst_jack_ring_buffer_close_device (GstRingBuffer * buf)
384 {
385   GstJackAudioSink *sink;
386
387   sink = GST_JACK_AUDIO_SINK (GST_OBJECT_PARENT (buf));
388
389   GST_DEBUG_OBJECT (sink, "close");
390
391   gst_jack_audio_sink_free_channels (sink);
392   gst_jack_audio_client_free (sink->client);
393   sink->client = NULL;
394
395   return TRUE;
396 }
397
398 /* allocate a buffer and setup resources to process the audio samples of
399  * the format as specified in @spec.
400  *
401  * We allocate N jack ports, one for each channel. If we are asked to
402  * automatically make a connection with physical ports, we connect as many
403  * ports as there are physical ports, leaving leftover ports unconnected.
404  *
405  * It is assumed that samplerate and number of channels are acceptable since our
406  * getcaps method will always provide correct values. If unacceptable caps are
407  * received for some reason, we fail here.
408  */
409 static gboolean
410 gst_jack_ring_buffer_acquire (GstRingBuffer * buf, GstRingBufferSpec * spec)
411 {
412   GstJackAudioSink *sink;
413   GstJackRingBuffer *abuf;
414   const char **ports;
415   gint sample_rate, buffer_size;
416   gint i, channels, res;
417   jack_client_t *client;
418
419   sink = GST_JACK_AUDIO_SINK (GST_OBJECT_PARENT (buf));
420   abuf = GST_JACK_RING_BUFFER_CAST (buf);
421
422   GST_DEBUG_OBJECT (sink, "acquire");
423
424   client = gst_jack_audio_client_get_client (sink->client);
425
426   /* sample rate must be that of the server */
427   sample_rate = jack_get_sample_rate (client);
428   if (sample_rate != spec->rate)
429     goto wrong_samplerate;
430
431   channels = spec->channels;
432
433   if (!gst_jack_audio_sink_allocate_channels (sink, channels))
434     goto out_of_ports;
435
436   buffer_size = jack_get_buffer_size (client);
437
438   /* the segment size in bytes, this is large enough to hold a buffer of 32bit floats
439    * for all channels  */
440   spec->segsize = buffer_size * sizeof (gfloat) * channels;
441   spec->latency_time = gst_util_uint64_scale (spec->segsize,
442       (GST_SECOND / GST_USECOND), spec->rate * spec->bytes_per_sample);
443   /* segtotal based on buffer-time latency */
444   spec->segtotal = spec->buffer_time / spec->latency_time;
445   if (spec->segtotal < 2) {
446     spec->segtotal = 2;
447     spec->buffer_time = spec->latency_time * spec->segtotal;
448   }
449
450   GST_DEBUG_OBJECT (sink, "buffer time: %" G_GINT64_FORMAT " usec",
451       spec->buffer_time);
452   GST_DEBUG_OBJECT (sink, "latency time: %" G_GINT64_FORMAT " usec",
453       spec->latency_time);
454   GST_DEBUG_OBJECT (sink, "buffer_size %d, segsize %d, segtotal %d",
455       buffer_size, spec->segsize, spec->segtotal);
456
457   /* allocate the ringbuffer memory now */
458   buf->data = gst_buffer_new_and_alloc (spec->segtotal * spec->segsize);
459   memset (GST_BUFFER_DATA (buf->data), 0, GST_BUFFER_SIZE (buf->data));
460
461   if ((res = gst_jack_audio_client_set_active (sink->client, TRUE)))
462     goto could_not_activate;
463
464   /* if we need to automatically connect the ports, do so now. We must do this
465    * after activating the client. */
466   if (sink->connect == GST_JACK_CONNECT_AUTO
467       || sink->connect == GST_JACK_CONNECT_AUTO_FORCED) {
468     /* find all the physical input ports. A physical input port is a port
469      * associated with a hardware device. Someone needs connect to a physical
470      * port in order to hear something. */
471     ports = jack_get_ports (client, NULL, NULL,
472         JackPortIsPhysical | JackPortIsInput);
473     if (ports == NULL) {
474       /* no ports? fine then we don't do anything except for posting a warning
475        * message. */
476       GST_ELEMENT_WARNING (sink, RESOURCE, NOT_FOUND, (NULL),
477           ("No physical input ports found, leaving ports unconnected"));
478       goto done;
479     }
480
481     for (i = 0; i < channels; i++) {
482       /* stop when all input ports are exhausted */
483       if (ports[i] == NULL) {
484         /* post a warning that we could not connect all ports */
485         GST_ELEMENT_WARNING (sink, RESOURCE, NOT_FOUND, (NULL),
486             ("No more physical ports, leaving some ports unconnected"));
487         break;
488       }
489       GST_DEBUG_OBJECT (sink, "try connecting to %s",
490           jack_port_name (sink->ports[i]));
491       /* connect the port to a physical port */
492       res = jack_connect (client, jack_port_name (sink->ports[i]), ports[i]);
493       if (res != 0 && res != EEXIST)
494         goto cannot_connect;
495     }
496     free (ports);
497   }
498 done:
499
500   abuf->sample_rate = sample_rate;
501   abuf->buffer_size = buffer_size;
502   abuf->channels = spec->channels;
503
504   return TRUE;
505
506   /* ERRORS */
507 wrong_samplerate:
508   {
509     GST_ELEMENT_ERROR (sink, RESOURCE, SETTINGS, (NULL),
510         ("Wrong samplerate, server is running at %d and we received %d",
511             sample_rate, spec->rate));
512     return FALSE;
513   }
514 out_of_ports:
515   {
516     GST_ELEMENT_ERROR (sink, RESOURCE, SETTINGS, (NULL),
517         ("Cannot allocate more Jack ports"));
518     return FALSE;
519   }
520 could_not_activate:
521   {
522     GST_ELEMENT_ERROR (sink, RESOURCE, SETTINGS, (NULL),
523         ("Could not activate client (%d:%s)", res, g_strerror (res)));
524     return FALSE;
525   }
526 cannot_connect:
527   {
528     GST_ELEMENT_ERROR (sink, RESOURCE, SETTINGS, (NULL),
529         ("Could not connect output ports to physical ports (%d:%s)",
530             res, g_strerror (res)));
531     free (ports);
532     return FALSE;
533   }
534 }
535
536 /* function is called with LOCK */
537 static gboolean
538 gst_jack_ring_buffer_release (GstRingBuffer * buf)
539 {
540   GstJackAudioSink *sink;
541   GstJackRingBuffer *abuf;
542   gint res;
543
544   abuf = GST_JACK_RING_BUFFER_CAST (buf);
545   sink = GST_JACK_AUDIO_SINK (GST_OBJECT_PARENT (buf));
546
547   GST_DEBUG_OBJECT (sink, "release");
548
549   if ((res = gst_jack_audio_client_set_active (sink->client, FALSE))) {
550     /* we only warn, this means the server is probably shut down and the client
551      * is gone anyway. */
552     GST_ELEMENT_WARNING (sink, RESOURCE, CLOSE, (NULL),
553         ("Could not deactivate Jack client (%d)", res));
554   }
555
556   abuf->channels = -1;
557   abuf->buffer_size = -1;
558   abuf->sample_rate = -1;
559
560   /* free the buffer */
561   gst_buffer_unref (buf->data);
562   buf->data = NULL;
563
564   return TRUE;
565 }
566
567 static gboolean
568 gst_jack_ring_buffer_start (GstRingBuffer * buf)
569 {
570   GstJackAudioSink *sink;
571
572   sink = GST_JACK_AUDIO_SINK (GST_OBJECT_PARENT (buf));
573
574   GST_DEBUG_OBJECT (sink, "start");
575
576   return TRUE;
577 }
578
579 static gboolean
580 gst_jack_ring_buffer_pause (GstRingBuffer * buf)
581 {
582   GstJackAudioSink *sink;
583
584   sink = GST_JACK_AUDIO_SINK (GST_OBJECT_PARENT (buf));
585
586   GST_DEBUG_OBJECT (sink, "pause");
587
588   return TRUE;
589 }
590
591 static gboolean
592 gst_jack_ring_buffer_stop (GstRingBuffer * buf)
593 {
594   GstJackAudioSink *sink;
595
596   sink = GST_JACK_AUDIO_SINK (GST_OBJECT_PARENT (buf));
597
598   GST_DEBUG_OBJECT (sink, "stop");
599
600   return TRUE;
601 }
602
603 static guint
604 gst_jack_ring_buffer_delay (GstRingBuffer * buf)
605 {
606   GstJackAudioSink *sink;
607   guint i, res = 0, latency;
608   jack_client_t *client;
609
610   sink = GST_JACK_AUDIO_SINK (GST_OBJECT_PARENT (buf));
611   client = gst_jack_audio_client_get_client (sink->client);
612
613   for (i = 0; i < sink->port_count; i++) {
614     latency = jack_port_get_total_latency (client, sink->ports[i]);
615     if (latency > res)
616       res = latency;
617   }
618
619   GST_LOG_OBJECT (sink, "delay %u", res);
620
621   return res;
622 }
623
624 /* elementfactory information */
625 static const GstElementDetails gst_jack_audio_sink_details =
626 GST_ELEMENT_DETAILS ("Audio Sink (Jack)",
627     "Sink/Audio",
628     "Output to Jack",
629     "Wim Taymans <wim@fluendo.com>");
630
631 static GstStaticPadTemplate jackaudiosink_sink_factory =
632 GST_STATIC_PAD_TEMPLATE ("sink",
633     GST_PAD_SINK,
634     GST_PAD_ALWAYS,
635     GST_STATIC_CAPS ("audio/x-raw-float, "
636         "endianness = (int) { " G_STRINGIFY (G_BYTE_ORDER) " }, "
637         "width = (int) 32, "
638         "rate = (int) [ 1, MAX ], " "channels = (int) [ 1, MAX ]")
639     );
640
641 /* AudioSink signals and args */
642 enum
643 {
644   /* FILL ME */
645   SIGNAL_LAST
646 };
647
648 #define DEFAULT_PROP_CONNECT    GST_JACK_CONNECT_AUTO
649 #define DEFAULT_PROP_SERVER     NULL
650
651 enum
652 {
653   PROP_0,
654   PROP_CONNECT,
655   PROP_SERVER,
656   PROP_LAST
657 };
658
659 #define _do_init(bla) \
660     GST_DEBUG_CATEGORY_INIT (gst_jack_audio_sink_debug, "jacksink", 0, "jacksink element");
661
662 GST_BOILERPLATE_FULL (GstJackAudioSink, gst_jack_audio_sink, GstBaseAudioSink,
663     GST_TYPE_BASE_AUDIO_SINK, _do_init);
664
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 (element_class, &gst_jack_audio_sink_details);
680
681   gst_element_class_add_pad_template (element_class,
682       gst_static_pad_template_get (&jackaudiosink_sink_factory));
683 }
684
685 static void
686 gst_jack_audio_sink_class_init (GstJackAudioSinkClass * klass)
687 {
688   GObjectClass *gobject_class;
689   GstElementClass *gstelement_class;
690   GstBaseSinkClass *gstbasesink_class;
691   GstBaseAudioSinkClass *gstbaseaudiosink_class;
692
693   gobject_class = (GObjectClass *) klass;
694   gstelement_class = (GstElementClass *) klass;
695   gstbasesink_class = (GstBaseSinkClass *) klass;
696   gstbaseaudiosink_class = (GstBaseAudioSinkClass *) klass;
697
698   gobject_class->get_property =
699       GST_DEBUG_FUNCPTR (gst_jack_audio_sink_get_property);
700   gobject_class->set_property =
701       GST_DEBUG_FUNCPTR (gst_jack_audio_sink_set_property);
702
703   g_object_class_install_property (gobject_class, PROP_CONNECT,
704       g_param_spec_enum ("connect", "Connect",
705           "Specify how the output ports will be connected",
706           GST_TYPE_JACK_CONNECT, DEFAULT_PROP_CONNECT, G_PARAM_READWRITE));
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));
712
713   gstbasesink_class->get_caps = GST_DEBUG_FUNCPTR (gst_jack_audio_sink_getcaps);
714
715   gstbaseaudiosink_class->create_ringbuffer =
716       GST_DEBUG_FUNCPTR (gst_jack_audio_sink_create_ringbuffer);
717
718   /* ref class from a thread-safe context to work around missing bit of
719    * thread-safety in GObject */
720   g_type_class_ref (GST_TYPE_JACK_RING_BUFFER);
721
722   gst_jack_audio_client_init ();
723 }
724
725 static void
726 gst_jack_audio_sink_init (GstJackAudioSink * sink,
727     GstJackAudioSinkClass * g_class)
728 {
729   sink->connect = DEFAULT_PROP_CONNECT;
730   sink->server = g_strdup (DEFAULT_PROP_SERVER);
731   sink->ports = NULL;
732   sink->port_count = 0;
733 }
734
735 static void
736 gst_jack_audio_sink_set_property (GObject * object, guint prop_id,
737     const GValue * value, GParamSpec * pspec)
738 {
739   GstJackAudioSink *sink;
740
741   sink = GST_JACK_AUDIO_SINK (object);
742
743   switch (prop_id) {
744     case PROP_CONNECT:
745       sink->connect = g_value_get_enum (value);
746       break;
747     case PROP_SERVER:
748       g_free (sink->server);
749       sink->server = g_value_dup_string (value);
750       break;
751     default:
752       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
753       break;
754   }
755 }
756
757 static void
758 gst_jack_audio_sink_get_property (GObject * object, guint prop_id,
759     GValue * value, GParamSpec * pspec)
760 {
761   GstJackAudioSink *sink;
762
763   sink = GST_JACK_AUDIO_SINK (object);
764
765   switch (prop_id) {
766     case PROP_CONNECT:
767       g_value_set_enum (value, sink->connect);
768       break;
769     case PROP_SERVER:
770       g_value_set_string (value, sink->server);
771       break;
772     default:
773       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
774       break;
775   }
776 }
777
778 static GstCaps *
779 gst_jack_audio_sink_getcaps (GstBaseSink * bsink)
780 {
781   GstJackAudioSink *sink = GST_JACK_AUDIO_SINK (bsink);
782   const char **ports;
783   gint min, max;
784   gint rate;
785   jack_client_t *client;
786
787   if (sink->client == NULL)
788     goto no_client;
789
790   client = gst_jack_audio_client_get_client (sink->client);
791
792   if (sink->connect == GST_JACK_CONNECT_AUTO) {
793     /* get a port count, this is the number of channels we can automatically
794      * connect. */
795     ports = jack_get_ports (client, NULL, NULL,
796         JackPortIsPhysical | JackPortIsInput);
797     max = 0;
798     if (ports != NULL) {
799       for (; ports[max]; max++);
800       free (ports);
801     } else
802       max = 0;
803   } else {
804     /* we allow any number of pads, something else is going to connect the
805      * pads. */
806     max = G_MAXINT;
807   }
808   min = MIN (1, max);
809
810   rate = jack_get_sample_rate (client);
811
812   GST_DEBUG_OBJECT (sink, "got %d-%d ports, samplerate: %d", min, max, rate);
813
814   if (!sink->caps) {
815     sink->caps = gst_caps_new_simple ("audio/x-raw-float",
816         "endianness", G_TYPE_INT, G_BYTE_ORDER,
817         "width", G_TYPE_INT, 32,
818         "rate", G_TYPE_INT, rate,
819         "channels", GST_TYPE_INT_RANGE, min, max, NULL);
820   }
821   GST_INFO_OBJECT (sink, "returning caps %" GST_PTR_FORMAT, sink->caps);
822
823   return gst_caps_ref (sink->caps);
824
825   /* ERRORS */
826 no_client:
827   {
828     GST_DEBUG_OBJECT (sink, "device not open, using template caps");
829     /* base class will get template caps for us when we return NULL */
830     return NULL;
831   }
832 }
833
834 static GstRingBuffer *
835 gst_jack_audio_sink_create_ringbuffer (GstBaseAudioSink * sink)
836 {
837   GstRingBuffer *buffer;
838
839   buffer = g_object_new (GST_TYPE_JACK_RING_BUFFER, NULL);
840   GST_DEBUG_OBJECT (sink, "created ringbuffer @%p", buffer);
841
842   return buffer;
843 }