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