update for ringbuffer change
[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, #GstAudioRingBuffer
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_AUDIO_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   GstAudioRingBufferClass *gstringbuffer_class;
162
163   gstringbuffer_class = (GstAudioRingBufferClass *) 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   GstAudioRingBuffer *buf;
190   gint readseg, len;
191   guint8 *readptr;
192   gint i, j, flen, channels;
193   sample_t *data;
194
195   buf = GST_AUDIO_RING_BUFFER_CAST (arg);
196   sink = GST_JACK_AUDIO_SINK (GST_OBJECT_PARENT (buf));
197
198   channels = GST_AUDIO_INFO_CHANNELS (&buf->spec.info);
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_audio_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_audio_ring_buffer_clear (buf, readseg);
227
228     /* we wrote one segment */
229     gst_audio_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 (GstAudioRingBuffer * 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   name = g_get_application_name ();
333   if (!name)
334     name = "GStreamer";
335
336   sink->client = gst_jack_audio_client_new (name, sink->server,
337       sink->jclient,
338       GST_JACK_CLIENT_SINK,
339       jack_shutdown_cb,
340       jack_process_cb, jack_buffer_size_cb, jack_sample_rate_cb, buf, &status);
341   if (sink->client == NULL)
342     goto could_not_open;
343
344   GST_DEBUG_OBJECT (sink, "opened");
345
346   return TRUE;
347
348   /* ERRORS */
349 could_not_open:
350   {
351     if (status & JackServerFailed) {
352       GST_ELEMENT_ERROR (sink, RESOURCE, NOT_FOUND,
353           (_("Jack server not found")),
354           ("Cannot connect to the Jack server (status %d)", status));
355     } else {
356       GST_ELEMENT_ERROR (sink, RESOURCE, OPEN_WRITE,
357           (NULL), ("Jack client open error (status %d)", status));
358     }
359     return FALSE;
360   }
361 }
362
363 /* close the connection with the server
364  */
365 static gboolean
366 gst_jack_ring_buffer_close_device (GstAudioRingBuffer * buf)
367 {
368   GstJackAudioSink *sink;
369
370   sink = GST_JACK_AUDIO_SINK (GST_OBJECT_PARENT (buf));
371
372   GST_DEBUG_OBJECT (sink, "close");
373
374   gst_jack_audio_sink_free_channels (sink);
375   gst_jack_audio_client_free (sink->client);
376   sink->client = NULL;
377
378   return TRUE;
379 }
380
381 /* allocate a buffer and setup resources to process the audio samples of
382  * the format as specified in @spec.
383  *
384  * We allocate N jack ports, one for each channel. If we are asked to
385  * automatically make a connection with physical ports, we connect as many
386  * ports as there are physical ports, leaving leftover ports unconnected.
387  *
388  * It is assumed that samplerate and number of channels are acceptable since our
389  * getcaps method will always provide correct values. If unacceptable caps are
390  * received for some reason, we fail here.
391  */
392 static gboolean
393 gst_jack_ring_buffer_acquire (GstAudioRingBuffer * buf,
394     GstAudioRingBufferSpec * spec)
395 {
396   GstJackAudioSink *sink;
397   GstJackRingBuffer *abuf;
398   const char **ports;
399   gint sample_rate, buffer_size;
400   gint i, rate, bpf, channels, res;
401   jack_client_t *client;
402
403   sink = GST_JACK_AUDIO_SINK (GST_OBJECT_PARENT (buf));
404   abuf = GST_JACK_RING_BUFFER_CAST (buf);
405
406   GST_DEBUG_OBJECT (sink, "acquire");
407
408   client = gst_jack_audio_client_get_client (sink->client);
409
410   rate = GST_AUDIO_INFO_RATE (&spec->info);
411
412   /* sample rate must be that of the server */
413   sample_rate = jack_get_sample_rate (client);
414   if (sample_rate != rate)
415     goto wrong_samplerate;
416
417   channels = GST_AUDIO_INFO_CHANNELS (&spec->info);
418   bpf = GST_AUDIO_INFO_BPF (&spec->info);
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), rate * bpf);
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->size = spec->segtotal * spec->segsize;
446   buf->memory = g_malloc0 (buf->size);
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 = 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, 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 (GstAudioRingBuffer * 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   g_free (buf->memory);
549   buf->memory = NULL;
550
551   return TRUE;
552 }
553
554 static gboolean
555 gst_jack_ring_buffer_start (GstAudioRingBuffer * 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 (GstAudioRingBuffer * 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 (GstAudioRingBuffer * 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 (GstAudioRingBuffer * 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 (GstAudioRingBuffer * 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, "
639         "format = (string) " GST_JACK_FORMAT_STR ", "
640         "rate = (int) [ 1, MAX ], " "channels = (int) [ 1, MAX ]")
641     );
642
643 /* AudioSink signals and args */
644 enum
645 {
646   /* FILL ME */
647   SIGNAL_LAST
648 };
649
650 #define DEFAULT_PROP_CONNECT    GST_JACK_CONNECT_AUTO
651 #define DEFAULT_PROP_SERVER     NULL
652
653 enum
654 {
655   PROP_0,
656   PROP_CONNECT,
657   PROP_SERVER,
658   PROP_CLIENT,
659   PROP_LAST
660 };
661
662 #define gst_jack_audio_sink_parent_class parent_class
663 G_DEFINE_TYPE (GstJackAudioSink, gst_jack_audio_sink, GST_TYPE_BASE_AUDIO_SINK);
664
665 static void gst_jack_audio_sink_dispose (GObject * object);
666 static void gst_jack_audio_sink_set_property (GObject * object, guint prop_id,
667     const GValue * value, GParamSpec * pspec);
668 static void gst_jack_audio_sink_get_property (GObject * object, guint prop_id,
669     GValue * value, GParamSpec * pspec);
670
671 static GstCaps *gst_jack_audio_sink_getcaps (GstBaseSink * bsink,
672     GstCaps * filter);
673 static GstAudioRingBuffer
674     * gst_jack_audio_sink_create_ringbuffer (GstBaseAudioSink * sink);
675
676 static void
677 gst_jack_audio_sink_class_init (GstJackAudioSinkClass * klass)
678 {
679   GObjectClass *gobject_class;
680   GstElementClass *gstelement_class;
681   GstBaseSinkClass *gstbasesink_class;
682   GstBaseAudioSinkClass *gstbaseaudiosink_class;
683
684   GST_DEBUG_CATEGORY_INIT (gst_jack_audio_sink_debug, "jacksink", 0,
685       "jacksink element");
686
687   gobject_class = (GObjectClass *) klass;
688   gstelement_class = (GstElementClass *) klass;
689   gstbasesink_class = (GstBaseSinkClass *) klass;
690   gstbaseaudiosink_class = (GstBaseAudioSinkClass *) klass;
691
692   gobject_class->dispose = gst_jack_audio_sink_dispose;
693   gobject_class->get_property = gst_jack_audio_sink_get_property;
694   gobject_class->set_property = gst_jack_audio_sink_set_property;
695
696   g_object_class_install_property (gobject_class, PROP_CONNECT,
697       g_param_spec_enum ("connect", "Connect",
698           "Specify how the output ports will be connected",
699           GST_TYPE_JACK_CONNECT, DEFAULT_PROP_CONNECT,
700           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
701
702   g_object_class_install_property (gobject_class, PROP_SERVER,
703       g_param_spec_string ("server", "Server",
704           "The Jack server to connect to (NULL = default)",
705           DEFAULT_PROP_SERVER, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
706
707   g_object_class_install_property (gobject_class, PROP_CLIENT,
708       g_param_spec_boxed ("client", "JackClient", "Handle for jack client",
709           GST_TYPE_JACK_CLIENT,
710           GST_PARAM_MUTABLE_READY | G_PARAM_READWRITE |
711           G_PARAM_STATIC_STRINGS));
712
713   gst_element_class_set_details_simple (gstelement_class, "Audio Sink (Jack)",
714       "Sink/Audio", "Output audio to a JACK server",
715       "Wim Taymans <wim.taymans@gmail.com>");
716
717   gst_element_class_add_pad_template (gstelement_class,
718       gst_static_pad_template_get (&jackaudiosink_sink_factory));
719
720   gstbasesink_class->get_caps = GST_DEBUG_FUNCPTR (gst_jack_audio_sink_getcaps);
721
722   gstbaseaudiosink_class->create_ringbuffer =
723       GST_DEBUG_FUNCPTR (gst_jack_audio_sink_create_ringbuffer);
724
725   /* ref class from a thread-safe context to work around missing bit of
726    * thread-safety in GObject */
727   g_type_class_ref (GST_TYPE_JACK_RING_BUFFER);
728
729   gst_jack_audio_client_init ();
730 }
731
732 static void
733 gst_jack_audio_sink_init (GstJackAudioSink * sink)
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   sink->buffers = NULL;
741 }
742
743 static void
744 gst_jack_audio_sink_dispose (GObject * object)
745 {
746   GstJackAudioSink *sink = GST_JACK_AUDIO_SINK (object);
747
748   gst_caps_replace (&sink->caps, NULL);
749   G_OBJECT_CLASS (parent_class)->dispose (object);
750 }
751
752 static void
753 gst_jack_audio_sink_set_property (GObject * object, guint prop_id,
754     const GValue * value, GParamSpec * pspec)
755 {
756   GstJackAudioSink *sink;
757
758   sink = GST_JACK_AUDIO_SINK (object);
759
760   switch (prop_id) {
761     case PROP_CONNECT:
762       sink->connect = g_value_get_enum (value);
763       break;
764     case PROP_SERVER:
765       g_free (sink->server);
766       sink->server = g_value_dup_string (value);
767       break;
768     case PROP_CLIENT:
769       if (GST_STATE (sink) == GST_STATE_NULL ||
770           GST_STATE (sink) == GST_STATE_READY) {
771         sink->jclient = g_value_get_boxed (value);
772       }
773       break;
774     default:
775       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
776       break;
777   }
778 }
779
780 static void
781 gst_jack_audio_sink_get_property (GObject * object, guint prop_id,
782     GValue * value, GParamSpec * pspec)
783 {
784   GstJackAudioSink *sink;
785
786   sink = GST_JACK_AUDIO_SINK (object);
787
788   switch (prop_id) {
789     case PROP_CONNECT:
790       g_value_set_enum (value, sink->connect);
791       break;
792     case PROP_SERVER:
793       g_value_set_string (value, sink->server);
794       break;
795     case PROP_CLIENT:
796       g_value_set_boxed (value, sink->jclient);
797       break;
798     default:
799       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
800       break;
801   }
802 }
803
804 static GstCaps *
805 gst_jack_audio_sink_getcaps (GstBaseSink * bsink, GstCaps * filter)
806 {
807   GstJackAudioSink *sink = GST_JACK_AUDIO_SINK (bsink);
808   const char **ports;
809   gint min, max;
810   gint rate;
811   jack_client_t *client;
812
813   if (sink->client == NULL)
814     goto no_client;
815
816   client = gst_jack_audio_client_get_client (sink->client);
817
818   if (sink->connect == GST_JACK_CONNECT_AUTO) {
819     /* get a port count, this is the number of channels we can automatically
820      * connect. */
821     ports = jack_get_ports (client, NULL, NULL,
822         JackPortIsPhysical | JackPortIsInput);
823     max = 0;
824     if (ports != NULL) {
825       for (; ports[max]; max++);
826       free (ports);
827     } else
828       max = 0;
829   } else {
830     /* we allow any number of pads, something else is going to connect the
831      * pads. */
832     max = G_MAXINT;
833   }
834   min = MIN (1, max);
835
836   rate = jack_get_sample_rate (client);
837
838   GST_DEBUG_OBJECT (sink, "got %d-%d ports, samplerate: %d", min, max, rate);
839
840   if (!sink->caps) {
841     sink->caps = gst_caps_new_simple ("audio/x-raw",
842         "format", G_TYPE_STRING, GST_JACK_FORMAT_STR,
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 GstAudioRingBuffer *
860 gst_jack_audio_sink_create_ringbuffer (GstBaseAudioSink * sink)
861 {
862   GstAudioRingBuffer *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 }