audioringbuffer: avoid division by 0 when outputting debug info
[platform/upstream/gstreamer.git] / gst-libs / gst / audio / gstaudioringbuffer.c
1 /* GStreamer
2  * Copyright (C) 2005 Wim Taymans <wim@fluendo.com>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19
20 /**
21  * SECTION:gstaudioringbuffer
22  * @short_description: Base class for audio ringbuffer implementations
23  * @see_also: #GstAudioBaseSink, #GstAudioSink
24  *
25  * <refsect2>
26  * <para>
27  * This object is the base class for audio ringbuffers used by the base
28  * audio source and sink classes.
29  * </para>
30  * <para>
31  * The ringbuffer abstracts a circular buffer of data. One reader and
32  * one writer can operate on the data from different threads in a lockfree
33  * manner. The base class is sufficiently flexible to be used as an
34  * abstraction for DMA based ringbuffers as well as a pure software
35  * implementations.
36  * </para>
37  * </refsect2>
38  *
39  * Last reviewed on 2006-02-02 (0.10.4)
40  */
41
42 #include <string.h>
43
44 #include <gst/audio/audio.h>
45 #include "gstaudioringbuffer.h"
46
47 GST_DEBUG_CATEGORY_STATIC (gst_audio_ring_buffer_debug);
48 #define GST_CAT_DEFAULT gst_audio_ring_buffer_debug
49
50 static void gst_audio_ring_buffer_dispose (GObject * object);
51 static void gst_audio_ring_buffer_finalize (GObject * object);
52
53 static gboolean gst_audio_ring_buffer_pause_unlocked (GstAudioRingBuffer * buf);
54 static void default_clear_all (GstAudioRingBuffer * buf);
55 static guint default_commit (GstAudioRingBuffer * buf, guint64 * sample,
56     guint8 * data, gint in_samples, gint out_samples, gint * accum);
57
58 /* ringbuffer abstract base class */
59 G_DEFINE_ABSTRACT_TYPE (GstAudioRingBuffer, gst_audio_ring_buffer,
60     GST_TYPE_OBJECT);
61
62 static void
63 gst_audio_ring_buffer_class_init (GstAudioRingBufferClass * klass)
64 {
65   GObjectClass *gobject_class;
66   GstAudioRingBufferClass *gstaudioringbuffer_class;
67
68   gobject_class = (GObjectClass *) klass;
69   gstaudioringbuffer_class = (GstAudioRingBufferClass *) klass;
70
71   GST_DEBUG_CATEGORY_INIT (gst_audio_ring_buffer_debug, "ringbuffer", 0,
72       "ringbuffer class");
73
74   gobject_class->dispose = gst_audio_ring_buffer_dispose;
75   gobject_class->finalize = gst_audio_ring_buffer_finalize;
76
77   gstaudioringbuffer_class->clear_all = GST_DEBUG_FUNCPTR (default_clear_all);
78   gstaudioringbuffer_class->commit = GST_DEBUG_FUNCPTR (default_commit);
79 }
80
81 static void
82 gst_audio_ring_buffer_init (GstAudioRingBuffer * ringbuffer)
83 {
84   ringbuffer->open = FALSE;
85   ringbuffer->acquired = FALSE;
86   ringbuffer->state = GST_AUDIO_RING_BUFFER_STATE_STOPPED;
87   g_cond_init (&ringbuffer->cond);
88   ringbuffer->waiting = 0;
89   ringbuffer->empty_seg = NULL;
90   ringbuffer->flushing = TRUE;
91 }
92
93 static void
94 gst_audio_ring_buffer_dispose (GObject * object)
95 {
96   GstAudioRingBuffer *ringbuffer = GST_AUDIO_RING_BUFFER (object);
97
98   gst_caps_replace (&ringbuffer->spec.caps, NULL);
99
100   G_OBJECT_CLASS (gst_audio_ring_buffer_parent_class)->dispose (G_OBJECT
101       (ringbuffer));
102 }
103
104 static void
105 gst_audio_ring_buffer_finalize (GObject * object)
106 {
107   GstAudioRingBuffer *ringbuffer = GST_AUDIO_RING_BUFFER (object);
108
109   g_cond_clear (&ringbuffer->cond);
110   g_free (ringbuffer->empty_seg);
111
112   G_OBJECT_CLASS (gst_audio_ring_buffer_parent_class)->finalize (G_OBJECT
113       (ringbuffer));
114 }
115
116 #ifndef GST_DISABLE_GST_DEBUG
117 static const gchar *format_type_names[] = {
118   "raw",
119   "mu law",
120   "a law",
121   "ima adpcm",
122   "mpeg",
123   "gsm",
124   "iec958",
125   "ac3",
126   "eac3",
127   "dts",
128   "aac mpeg2",
129   "aac mpeg4"
130 };
131 #endif
132
133 /**
134  * gst_audio_ring_buffer_debug_spec_caps:
135  * @spec: the spec to debug
136  *
137  * Print debug info about the parsed caps in @spec to the debug log.
138  */
139 void
140 gst_audio_ring_buffer_debug_spec_caps (GstAudioRingBufferSpec * spec)
141 {
142 #if 0
143   gint i, bytes;
144 #endif
145
146   GST_DEBUG ("spec caps: %p %" GST_PTR_FORMAT, spec->caps, spec->caps);
147   GST_DEBUG ("parsed caps: type:         %d, '%s'", spec->type,
148       format_type_names[spec->type]);
149 #if 0
150   GST_DEBUG ("parsed caps: width:        %d", spec->width);
151   GST_DEBUG ("parsed caps: sign:         %d", spec->sign);
152   GST_DEBUG ("parsed caps: bigend:       %d", spec->bigend);
153   GST_DEBUG ("parsed caps: rate:         %d", spec->rate);
154   GST_DEBUG ("parsed caps: channels:     %d", spec->channels);
155   GST_DEBUG ("parsed caps: sample bytes: %d", spec->bytes_per_sample);
156   bytes = (spec->width >> 3) * spec->channels;
157   for (i = 0; i < bytes; i++) {
158     GST_DEBUG ("silence byte %d: %02x", i, spec->silence_sample[i]);
159   }
160 #endif
161 }
162
163 /**
164  * gst_audio_ring_buffer_debug_spec_buff:
165  * @spec: the spec to debug
166  *
167  * Print debug info about the buffer sized in @spec to the debug log.
168  */
169 void
170 gst_audio_ring_buffer_debug_spec_buff (GstAudioRingBufferSpec * spec)
171 {
172   gint bpf = GST_AUDIO_INFO_BPF (&spec->info);
173
174   GST_DEBUG ("acquire ringbuffer: buffer time: %" G_GINT64_FORMAT " usec",
175       spec->buffer_time);
176   GST_DEBUG ("acquire ringbuffer: latency time: %" G_GINT64_FORMAT " usec",
177       spec->latency_time);
178   GST_DEBUG ("acquire ringbuffer: total segments: %d", spec->segtotal);
179   GST_DEBUG ("acquire ringbuffer: latency segments: %d", spec->seglatency);
180   GST_DEBUG ("acquire ringbuffer: segment size: %d bytes = %d samples",
181       spec->segsize, (bpf != 0) ? (spec->segsize / bpf) : -1);
182   GST_DEBUG ("acquire ringbuffer: buffer size: %d bytes = %d samples",
183       spec->segsize * spec->segtotal,
184       (bpf != 0) ? (spec->segsize * spec->segtotal / bpf) : -1);
185 }
186
187 /**
188  * gst_audio_ring_buffer_parse_caps:
189  * @spec: a spec
190  * @caps: a #GstCaps
191  *
192  * Parse @caps into @spec.
193  *
194  * Returns: TRUE if the caps could be parsed.
195  */
196 gboolean
197 gst_audio_ring_buffer_parse_caps (GstAudioRingBufferSpec * spec, GstCaps * caps)
198 {
199   const gchar *mimetype;
200   GstStructure *structure;
201   gint i;
202   GstAudioInfo info;
203
204   structure = gst_caps_get_structure (caps, 0);
205   gst_audio_info_init (&info);
206
207   /* we have to differentiate between int and float formats */
208   mimetype = gst_structure_get_name (structure);
209
210   if (g_str_equal (mimetype, "audio/x-raw")) {
211     if (!gst_audio_info_from_caps (&info, caps))
212       goto parse_error;
213
214     spec->type = GST_AUDIO_RING_BUFFER_FORMAT_TYPE_RAW;
215   } else if (g_str_equal (mimetype, "audio/x-alaw")) {
216     /* extract the needed information from the cap */
217     if (!(gst_structure_get_int (structure, "rate", &info.rate) &&
218             gst_structure_get_int (structure, "channels", &info.channels)))
219       goto parse_error;
220
221     spec->type = GST_AUDIO_RING_BUFFER_FORMAT_TYPE_A_LAW;
222     info.bpf = info.channels;
223   } else if (g_str_equal (mimetype, "audio/x-mulaw")) {
224     /* extract the needed information from the cap */
225     if (!(gst_structure_get_int (structure, "rate", &info.rate) &&
226             gst_structure_get_int (structure, "channels", &info.channels)))
227       goto parse_error;
228
229     spec->type = GST_AUDIO_RING_BUFFER_FORMAT_TYPE_MU_LAW;
230     info.bpf = info.channels;
231   } else if (g_str_equal (mimetype, "audio/x-iec958")) {
232     /* extract the needed information from the cap */
233     if (!(gst_structure_get_int (structure, "rate", &info.rate)))
234       goto parse_error;
235
236     spec->type = GST_AUDIO_RING_BUFFER_FORMAT_TYPE_IEC958;
237     info.bpf = 4;
238   } else if (g_str_equal (mimetype, "audio/x-ac3")) {
239     /* extract the needed information from the cap */
240     if (!(gst_structure_get_int (structure, "rate", &info.rate)))
241       goto parse_error;
242
243     spec->type = GST_AUDIO_RING_BUFFER_FORMAT_TYPE_AC3;
244     info.bpf = 4;
245   } else if (g_str_equal (mimetype, "audio/x-eac3")) {
246     /* extract the needed information from the cap */
247     if (!(gst_structure_get_int (structure, "rate", &info.rate)))
248       goto parse_error;
249
250     spec->type = GST_AUDIO_RING_BUFFER_FORMAT_TYPE_EAC3;
251     info.bpf = 16;
252   } else if (g_str_equal (mimetype, "audio/x-dts")) {
253     /* extract the needed information from the cap */
254     if (!(gst_structure_get_int (structure, "rate", &info.rate)))
255       goto parse_error;
256
257     spec->type = GST_AUDIO_RING_BUFFER_FORMAT_TYPE_DTS;
258     info.bpf = 4;
259   } else if (g_str_equal (mimetype, "audio/mpeg") &&
260       gst_structure_get_int (structure, "mpegaudioversion", &i) &&
261       (i == 1 || i == 2)) {
262     /* Now we know this is MPEG-1 or MPEG-2 (non AAC) */
263     /* extract the needed information from the cap */
264     if (!(gst_structure_get_int (structure, "rate", &info.rate)))
265       goto parse_error;
266
267     spec->type = GST_AUDIO_RING_BUFFER_FORMAT_TYPE_MPEG;
268     info.bpf = 4;
269   } else if (g_str_equal (mimetype, "audio/mpeg") &&
270       gst_structure_get_int (structure, "mpegversion", &i) &&
271       (i == 2 || i == 4) &&
272       !g_strcmp0 (gst_structure_get_string (structure, "stream-format"),
273           "adts")) {
274     /* MPEG-2 AAC or MPEG-4 AAC */
275     if (!(gst_structure_get_int (structure, "rate", &info.rate)))
276       goto parse_error;
277     spec->type = (i == 2) ? GST_AUDIO_RING_BUFFER_FORMAT_TYPE_MPEG2_AAC :
278         GST_AUDIO_RING_BUFFER_FORMAT_TYPE_MPEG4_AAC;
279     info.bpf = 4;
280   } else {
281     goto parse_error;
282   }
283
284   gst_caps_replace (&spec->caps, caps);
285
286   g_return_val_if_fail (spec->latency_time != 0, FALSE);
287
288   /* calculate suggested segsize and segtotal. segsize should be one unit
289    * of 'latency_time' samples, scaling for the fact that latency_time is
290    * currently stored in microseconds (FIXME: in 0.11) */
291   spec->segsize = gst_util_uint64_scale (info.rate * info.bpf,
292       spec->latency_time, GST_SECOND / GST_USECOND);
293   /* Round to an integer number of samples */
294   spec->segsize -= spec->segsize % info.bpf;
295
296   spec->segtotal = spec->buffer_time / spec->latency_time;
297   /* leave the latency undefined now, implementations can change it but if it's
298    * not changed, we assume the same value as segtotal */
299   spec->seglatency = -1;
300
301   spec->info = info;
302
303   gst_audio_ring_buffer_debug_spec_caps (spec);
304   gst_audio_ring_buffer_debug_spec_buff (spec);
305
306   return TRUE;
307
308   /* ERRORS */
309 parse_error:
310   {
311     GST_DEBUG ("could not parse caps");
312     return FALSE;
313   }
314 }
315
316 /**
317  * gst_audio_ring_buffer_convert:
318  * @buf: the #GstAudioRingBuffer
319  * @src_fmt: the source format
320  * @src_val: the source value
321  * @dest_fmt: the destination format
322  * @dest_val: a location to store the converted value
323  *
324  * Convert @src_val in @src_fmt to the equivalent value in @dest_fmt. The result
325  * will be put in @dest_val.
326  *
327  * Returns: TRUE if the conversion succeeded.
328  */
329 gboolean
330 gst_audio_ring_buffer_convert (GstAudioRingBuffer * buf,
331     GstFormat src_fmt, gint64 src_val, GstFormat dest_fmt, gint64 * dest_val)
332 {
333   gboolean res;
334
335   GST_OBJECT_LOCK (buf);
336   res =
337       gst_audio_info_convert (&buf->spec.info, src_fmt, src_val, dest_fmt,
338       dest_val);
339   GST_OBJECT_UNLOCK (buf);
340
341   return res;
342 }
343
344 /**
345  * gst_audio_ring_buffer_set_callback:
346  * @buf: the #GstAudioRingBuffer to set the callback on
347  * @cb: (scope async): the callback to set
348  * @user_data: user data passed to the callback
349  *
350  * Sets the given callback function on the buffer. This function
351  * will be called every time a segment has been written to a device.
352  *
353  * MT safe.
354  */
355 void
356 gst_audio_ring_buffer_set_callback (GstAudioRingBuffer * buf,
357     GstAudioRingBufferCallback cb, gpointer user_data)
358 {
359   g_return_if_fail (GST_IS_AUDIO_RING_BUFFER (buf));
360
361   GST_OBJECT_LOCK (buf);
362   buf->callback = cb;
363   buf->cb_data = user_data;
364   GST_OBJECT_UNLOCK (buf);
365 }
366
367
368 /**
369  * gst_audio_ring_buffer_open_device:
370  * @buf: the #GstAudioRingBuffer
371  *
372  * Open the audio device associated with the ring buffer. Does not perform any
373  * setup on the device. You must open the device before acquiring the ring
374  * buffer.
375  *
376  * Returns: TRUE if the device could be opened, FALSE on error.
377  *
378  * MT safe.
379  */
380 gboolean
381 gst_audio_ring_buffer_open_device (GstAudioRingBuffer * buf)
382 {
383   gboolean res = TRUE;
384   GstAudioRingBufferClass *rclass;
385
386   g_return_val_if_fail (GST_IS_AUDIO_RING_BUFFER (buf), FALSE);
387
388   GST_DEBUG_OBJECT (buf, "opening device");
389
390   GST_OBJECT_LOCK (buf);
391   if (G_UNLIKELY (buf->open))
392     goto was_opened;
393
394   buf->open = TRUE;
395
396   /* if this fails, something is wrong in this file */
397   g_assert (!buf->acquired);
398
399   rclass = GST_AUDIO_RING_BUFFER_GET_CLASS (buf);
400   if (G_LIKELY (rclass->open_device))
401     res = rclass->open_device (buf);
402
403   if (G_UNLIKELY (!res))
404     goto open_failed;
405
406   GST_DEBUG_OBJECT (buf, "opened device");
407
408 done:
409   GST_OBJECT_UNLOCK (buf);
410
411   return res;
412
413   /* ERRORS */
414 was_opened:
415   {
416     GST_DEBUG_OBJECT (buf, "Device for ring buffer already open");
417     g_warning ("Device for ring buffer %p already open, fix your code", buf);
418     res = TRUE;
419     goto done;
420   }
421 open_failed:
422   {
423     buf->open = FALSE;
424     GST_DEBUG_OBJECT (buf, "failed opening device");
425     goto done;
426   }
427 }
428
429 /**
430  * gst_audio_ring_buffer_close_device:
431  * @buf: the #GstAudioRingBuffer
432  *
433  * Close the audio device associated with the ring buffer. The ring buffer
434  * should already have been released via gst_audio_ring_buffer_release().
435  *
436  * Returns: TRUE if the device could be closed, FALSE on error.
437  *
438  * MT safe.
439  */
440 gboolean
441 gst_audio_ring_buffer_close_device (GstAudioRingBuffer * buf)
442 {
443   gboolean res = TRUE;
444   GstAudioRingBufferClass *rclass;
445
446   g_return_val_if_fail (GST_IS_AUDIO_RING_BUFFER (buf), FALSE);
447
448   GST_DEBUG_OBJECT (buf, "closing device");
449
450   GST_OBJECT_LOCK (buf);
451   if (G_UNLIKELY (!buf->open))
452     goto was_closed;
453
454   if (G_UNLIKELY (buf->acquired))
455     goto was_acquired;
456
457   buf->open = FALSE;
458
459   rclass = GST_AUDIO_RING_BUFFER_GET_CLASS (buf);
460   if (G_LIKELY (rclass->close_device))
461     res = rclass->close_device (buf);
462
463   if (G_UNLIKELY (!res))
464     goto close_error;
465
466   GST_DEBUG_OBJECT (buf, "closed device");
467
468 done:
469   GST_OBJECT_UNLOCK (buf);
470
471   return res;
472
473   /* ERRORS */
474 was_closed:
475   {
476     GST_DEBUG_OBJECT (buf, "Device for ring buffer already closed");
477     g_warning ("Device for ring buffer %p already closed, fix your code", buf);
478     res = TRUE;
479     goto done;
480   }
481 was_acquired:
482   {
483     GST_DEBUG_OBJECT (buf, "Resources for ring buffer still acquired");
484     g_critical ("Resources for ring buffer %p still acquired", buf);
485     res = FALSE;
486     goto done;
487   }
488 close_error:
489   {
490     buf->open = TRUE;
491     GST_DEBUG_OBJECT (buf, "error closing device");
492     goto done;
493   }
494 }
495
496 /**
497  * gst_audio_ring_buffer_device_is_open:
498  * @buf: the #GstAudioRingBuffer
499  *
500  * Checks the status of the device associated with the ring buffer.
501  *
502  * Returns: TRUE if the device was open, FALSE if it was closed.
503  *
504  * MT safe.
505  */
506 gboolean
507 gst_audio_ring_buffer_device_is_open (GstAudioRingBuffer * buf)
508 {
509   gboolean res = TRUE;
510
511   g_return_val_if_fail (GST_IS_AUDIO_RING_BUFFER (buf), FALSE);
512
513   GST_OBJECT_LOCK (buf);
514   res = buf->open;
515   GST_OBJECT_UNLOCK (buf);
516
517   return res;
518 }
519
520 /**
521  * gst_audio_ring_buffer_acquire:
522  * @buf: the #GstAudioRingBuffer to acquire
523  * @spec: the specs of the buffer
524  *
525  * Allocate the resources for the ringbuffer. This function fills
526  * in the data pointer of the ring buffer with a valid #GstBuffer
527  * to which samples can be written.
528  *
529  * Returns: TRUE if the device could be acquired, FALSE on error.
530  *
531  * MT safe.
532  */
533 gboolean
534 gst_audio_ring_buffer_acquire (GstAudioRingBuffer * buf,
535     GstAudioRingBufferSpec * spec)
536 {
537   gboolean res = FALSE;
538   GstAudioRingBufferClass *rclass;
539   gint segsize, bpf, i;
540
541   g_return_val_if_fail (GST_IS_AUDIO_RING_BUFFER (buf), FALSE);
542
543   GST_DEBUG_OBJECT (buf, "acquiring device %p", buf);
544
545   GST_OBJECT_LOCK (buf);
546   if (G_UNLIKELY (!buf->open))
547     goto not_opened;
548
549   if (G_UNLIKELY (buf->acquired))
550     goto was_acquired;
551
552   buf->acquired = TRUE;
553   buf->need_reorder = FALSE;
554
555   rclass = GST_AUDIO_RING_BUFFER_GET_CLASS (buf);
556   if (G_LIKELY (rclass->acquire))
557     res = rclass->acquire (buf, spec);
558
559   /* Only reorder for raw audio */
560   buf->need_reorder = (buf->need_reorder
561       && buf->spec.type == GST_AUDIO_RING_BUFFER_FORMAT_TYPE_RAW);
562
563   if (G_UNLIKELY (!res))
564     goto acquire_failed;
565
566   GST_INFO_OBJECT (buf, "Allocating an array for %d timestamps",
567       spec->segtotal);
568   buf->timestamps = g_slice_alloc0 (sizeof (GstClockTime) * spec->segtotal);
569   /* initialize array with invalid timestamps */
570   for (i = 0; i < spec->segtotal; i++) {
571     buf->timestamps[i] = GST_CLOCK_TIME_NONE;
572   }
573
574   if (G_UNLIKELY ((bpf = buf->spec.info.bpf) == 0))
575     goto invalid_bpf;
576
577   /* if the seglatency was overwritten with something else than -1, use it, else
578    * assume segtotal as the latency */
579   if (buf->spec.seglatency == -1)
580     buf->spec.seglatency = buf->spec.segtotal;
581
582   segsize = buf->spec.segsize;
583
584   buf->samples_per_seg = segsize / bpf;
585
586   /* create an empty segment */
587   g_free (buf->empty_seg);
588   buf->empty_seg = g_malloc (segsize);
589
590   if (buf->spec.type == GST_AUDIO_RING_BUFFER_FORMAT_TYPE_RAW) {
591     gst_audio_format_fill_silence (buf->spec.info.finfo, buf->empty_seg,
592         segsize);
593   } else {
594     /* FIXME, non-raw formats get 0 as the empty sample */
595     memset (buf->empty_seg, 0, segsize);
596   }
597   GST_DEBUG_OBJECT (buf, "acquired device");
598
599 done:
600   GST_OBJECT_UNLOCK (buf);
601
602   return res;
603
604   /* ERRORS */
605 not_opened:
606   {
607     GST_DEBUG_OBJECT (buf, "device not opened");
608     g_critical ("Device for %p not opened", buf);
609     res = FALSE;
610     goto done;
611   }
612 was_acquired:
613   {
614     res = TRUE;
615     GST_DEBUG_OBJECT (buf, "device was acquired");
616     goto done;
617   }
618 acquire_failed:
619   {
620     buf->acquired = FALSE;
621     GST_DEBUG_OBJECT (buf, "failed to acquire device");
622     goto done;
623   }
624 invalid_bpf:
625   {
626     g_warning
627         ("invalid bytes_per_frame from acquire ringbuffer %p, fix the element",
628         buf);
629     buf->acquired = FALSE;
630     res = FALSE;
631     goto done;
632   }
633 }
634
635 /**
636  * gst_audio_ring_buffer_release:
637  * @buf: the #GstAudioRingBuffer to release
638  *
639  * Free the resources of the ringbuffer.
640  *
641  * Returns: TRUE if the device could be released, FALSE on error.
642  *
643  * MT safe.
644  */
645 gboolean
646 gst_audio_ring_buffer_release (GstAudioRingBuffer * buf)
647 {
648   gboolean res = FALSE;
649   GstAudioRingBufferClass *rclass;
650
651   g_return_val_if_fail (GST_IS_AUDIO_RING_BUFFER (buf), FALSE);
652
653   GST_DEBUG_OBJECT (buf, "releasing device");
654
655   gst_audio_ring_buffer_stop (buf);
656
657   GST_OBJECT_LOCK (buf);
658
659   if (G_LIKELY (buf->timestamps)) {
660     GST_INFO_OBJECT (buf, "Freeing timestamp buffer, %d entries",
661         buf->spec.segtotal);
662     g_slice_free1 (sizeof (GstClockTime) * buf->spec.segtotal, buf->timestamps);
663     buf->timestamps = NULL;
664   }
665
666   if (G_UNLIKELY (!buf->acquired))
667     goto was_released;
668
669   buf->acquired = FALSE;
670
671   /* if this fails, something is wrong in this file */
672   g_assert (buf->open == TRUE);
673
674   rclass = GST_AUDIO_RING_BUFFER_GET_CLASS (buf);
675   if (G_LIKELY (rclass->release))
676     res = rclass->release (buf);
677
678   /* signal any waiters */
679   GST_DEBUG_OBJECT (buf, "signal waiter");
680   GST_AUDIO_RING_BUFFER_SIGNAL (buf);
681
682   if (G_UNLIKELY (!res))
683     goto release_failed;
684
685   g_free (buf->empty_seg);
686   buf->empty_seg = NULL;
687   gst_caps_replace (&buf->spec.caps, NULL);
688   gst_audio_info_init (&buf->spec.info);
689   GST_DEBUG_OBJECT (buf, "released device");
690
691 done:
692   GST_OBJECT_UNLOCK (buf);
693
694   return res;
695
696   /* ERRORS */
697 was_released:
698   {
699     res = TRUE;
700     GST_DEBUG_OBJECT (buf, "device was released");
701     goto done;
702   }
703 release_failed:
704   {
705     buf->acquired = TRUE;
706     GST_DEBUG_OBJECT (buf, "failed to release device");
707     goto done;
708   }
709 }
710
711 /**
712  * gst_audio_ring_buffer_is_acquired:
713  * @buf: the #GstAudioRingBuffer to check
714  *
715  * Check if the ringbuffer is acquired and ready to use.
716  *
717  * Returns: TRUE if the ringbuffer is acquired, FALSE on error.
718  *
719  * MT safe.
720  */
721 gboolean
722 gst_audio_ring_buffer_is_acquired (GstAudioRingBuffer * buf)
723 {
724   gboolean res;
725
726   g_return_val_if_fail (GST_IS_AUDIO_RING_BUFFER (buf), FALSE);
727
728   GST_OBJECT_LOCK (buf);
729   res = buf->acquired;
730   GST_OBJECT_UNLOCK (buf);
731
732   return res;
733 }
734
735 /**
736  * gst_audio_ring_buffer_activate:
737  * @buf: the #GstAudioRingBuffer to activate
738  * @active: the new mode
739  *
740  * Activate @buf to start or stop pulling data.
741  *
742  * MT safe.
743  *
744  * Returns: TRUE if the device could be activated in the requested mode,
745  * FALSE on error.
746  */
747 gboolean
748 gst_audio_ring_buffer_activate (GstAudioRingBuffer * buf, gboolean active)
749 {
750   gboolean res = FALSE;
751   GstAudioRingBufferClass *rclass;
752
753   g_return_val_if_fail (GST_IS_AUDIO_RING_BUFFER (buf), FALSE);
754
755   GST_DEBUG_OBJECT (buf, "activate device");
756
757   GST_OBJECT_LOCK (buf);
758   if (G_UNLIKELY (active && !buf->acquired))
759     goto not_acquired;
760
761   if (G_UNLIKELY (buf->active == active))
762     goto was_active;
763
764   rclass = GST_AUDIO_RING_BUFFER_GET_CLASS (buf);
765   /* if there is no activate function we assume it was started/released
766    * in the acquire method */
767   if (G_LIKELY (rclass->activate))
768     res = rclass->activate (buf, active);
769   else
770     res = TRUE;
771
772   if (G_UNLIKELY (!res))
773     goto activate_failed;
774
775   buf->active = active;
776
777 done:
778   GST_OBJECT_UNLOCK (buf);
779
780   return res;
781
782   /* ERRORS */
783 not_acquired:
784   {
785     GST_DEBUG_OBJECT (buf, "device not acquired");
786     g_critical ("Device for %p not acquired", buf);
787     res = FALSE;
788     goto done;
789   }
790 was_active:
791   {
792     res = TRUE;
793     GST_DEBUG_OBJECT (buf, "device was active in mode %d", active);
794     goto done;
795   }
796 activate_failed:
797   {
798     GST_DEBUG_OBJECT (buf, "failed to activate device");
799     goto done;
800   }
801 }
802
803 /**
804  * gst_audio_ring_buffer_is_active:
805  * @buf: the #GstAudioRingBuffer
806  *
807  * Check if @buf is activated.
808  *
809  * MT safe.
810  *
811  * Returns: TRUE if the device is active.
812  */
813 gboolean
814 gst_audio_ring_buffer_is_active (GstAudioRingBuffer * buf)
815 {
816   gboolean res;
817
818   g_return_val_if_fail (GST_IS_AUDIO_RING_BUFFER (buf), FALSE);
819
820   GST_OBJECT_LOCK (buf);
821   res = buf->active;
822   GST_OBJECT_UNLOCK (buf);
823
824   return res;
825 }
826
827
828 /**
829  * gst_audio_ring_buffer_set_flushing:
830  * @buf: the #GstAudioRingBuffer to flush
831  * @flushing: the new mode
832  *
833  * Set the ringbuffer to flushing mode or normal mode.
834  *
835  * MT safe.
836  */
837 void
838 gst_audio_ring_buffer_set_flushing (GstAudioRingBuffer * buf, gboolean flushing)
839 {
840   g_return_if_fail (GST_IS_AUDIO_RING_BUFFER (buf));
841
842   GST_OBJECT_LOCK (buf);
843   buf->flushing = flushing;
844
845   if (flushing) {
846     gst_audio_ring_buffer_pause_unlocked (buf);
847   } else {
848     gst_audio_ring_buffer_clear_all (buf);
849   }
850   GST_OBJECT_UNLOCK (buf);
851 }
852
853 /**
854  * gst_audio_ring_buffer_is_flushing:
855  * @buf: the #GstAudioRingBuffer
856  *
857  * Check if @buf is flushing.
858  *
859  * MT safe.
860  *
861  * Returns: TRUE if the device is flushing.
862  */
863 gboolean
864 gst_audio_ring_buffer_is_flushing (GstAudioRingBuffer * buf)
865 {
866   gboolean res;
867
868   g_return_val_if_fail (GST_IS_AUDIO_RING_BUFFER (buf), TRUE);
869
870   GST_OBJECT_LOCK (buf);
871   res = buf->flushing;
872   GST_OBJECT_UNLOCK (buf);
873
874   return res;
875 }
876
877 /**
878  * gst_audio_ring_buffer_start:
879  * @buf: the #GstAudioRingBuffer to start
880  *
881  * Start processing samples from the ringbuffer.
882  *
883  * Returns: TRUE if the device could be started, FALSE on error.
884  *
885  * MT safe.
886  */
887 gboolean
888 gst_audio_ring_buffer_start (GstAudioRingBuffer * buf)
889 {
890   gboolean res = FALSE;
891   GstAudioRingBufferClass *rclass;
892   gboolean resume = FALSE;
893
894   g_return_val_if_fail (GST_IS_AUDIO_RING_BUFFER (buf), FALSE);
895
896   GST_DEBUG_OBJECT (buf, "starting ringbuffer");
897
898   GST_OBJECT_LOCK (buf);
899   if (G_UNLIKELY (buf->flushing))
900     goto flushing;
901
902   if (G_UNLIKELY (!buf->acquired))
903     goto not_acquired;
904
905   if (G_UNLIKELY (g_atomic_int_get (&buf->may_start) == FALSE))
906     goto may_not_start;
907
908   /* if stopped, set to started */
909   res = g_atomic_int_compare_and_exchange (&buf->state,
910       GST_AUDIO_RING_BUFFER_STATE_STOPPED, GST_AUDIO_RING_BUFFER_STATE_STARTED);
911
912   if (!res) {
913     GST_DEBUG_OBJECT (buf, "was not stopped, try paused");
914     /* was not stopped, try from paused */
915     res = g_atomic_int_compare_and_exchange (&buf->state,
916         GST_AUDIO_RING_BUFFER_STATE_PAUSED,
917         GST_AUDIO_RING_BUFFER_STATE_STARTED);
918     if (!res) {
919       /* was not paused either, must be started then */
920       res = TRUE;
921       GST_DEBUG_OBJECT (buf, "was not paused, must have been started");
922       goto done;
923     }
924     resume = TRUE;
925     GST_DEBUG_OBJECT (buf, "resuming");
926   }
927
928   rclass = GST_AUDIO_RING_BUFFER_GET_CLASS (buf);
929   if (resume) {
930     if (G_LIKELY (rclass->resume))
931       res = rclass->resume (buf);
932   } else {
933     if (G_LIKELY (rclass->start))
934       res = rclass->start (buf);
935   }
936
937   if (G_UNLIKELY (!res)) {
938     buf->state = GST_AUDIO_RING_BUFFER_STATE_PAUSED;
939     GST_DEBUG_OBJECT (buf, "failed to start");
940   } else {
941     GST_DEBUG_OBJECT (buf, "started");
942   }
943
944 done:
945   GST_OBJECT_UNLOCK (buf);
946
947   return res;
948
949 flushing:
950   {
951     GST_DEBUG_OBJECT (buf, "we are flushing");
952     GST_OBJECT_UNLOCK (buf);
953     return FALSE;
954   }
955 not_acquired:
956   {
957     GST_DEBUG_OBJECT (buf, "we are not acquired");
958     GST_OBJECT_UNLOCK (buf);
959     return FALSE;
960   }
961 may_not_start:
962   {
963     GST_DEBUG_OBJECT (buf, "we may not start");
964     GST_OBJECT_UNLOCK (buf);
965     return FALSE;
966   }
967 }
968
969 static gboolean
970 gst_audio_ring_buffer_pause_unlocked (GstAudioRingBuffer * buf)
971 {
972   gboolean res = FALSE;
973   GstAudioRingBufferClass *rclass;
974
975   GST_DEBUG_OBJECT (buf, "pausing ringbuffer");
976
977   /* if started, set to paused */
978   res = g_atomic_int_compare_and_exchange (&buf->state,
979       GST_AUDIO_RING_BUFFER_STATE_STARTED, GST_AUDIO_RING_BUFFER_STATE_PAUSED);
980
981   if (!res)
982     goto not_started;
983
984   /* signal any waiters */
985   GST_DEBUG_OBJECT (buf, "signal waiter");
986   GST_AUDIO_RING_BUFFER_SIGNAL (buf);
987
988   rclass = GST_AUDIO_RING_BUFFER_GET_CLASS (buf);
989   if (G_LIKELY (rclass->pause))
990     res = rclass->pause (buf);
991
992   if (G_UNLIKELY (!res)) {
993     buf->state = GST_AUDIO_RING_BUFFER_STATE_STARTED;
994     GST_DEBUG_OBJECT (buf, "failed to pause");
995   } else {
996     GST_DEBUG_OBJECT (buf, "paused");
997   }
998
999   return res;
1000
1001 not_started:
1002   {
1003     /* was not started */
1004     GST_DEBUG_OBJECT (buf, "was not started");
1005     return TRUE;
1006   }
1007 }
1008
1009 /**
1010  * gst_audio_ring_buffer_pause:
1011  * @buf: the #GstAudioRingBuffer to pause
1012  *
1013  * Pause processing samples from the ringbuffer.
1014  *
1015  * Returns: TRUE if the device could be paused, FALSE on error.
1016  *
1017  * MT safe.
1018  */
1019 gboolean
1020 gst_audio_ring_buffer_pause (GstAudioRingBuffer * buf)
1021 {
1022   gboolean res = FALSE;
1023
1024   g_return_val_if_fail (GST_IS_AUDIO_RING_BUFFER (buf), FALSE);
1025
1026   GST_OBJECT_LOCK (buf);
1027   if (G_UNLIKELY (buf->flushing))
1028     goto flushing;
1029
1030   if (G_UNLIKELY (!buf->acquired))
1031     goto not_acquired;
1032
1033   res = gst_audio_ring_buffer_pause_unlocked (buf);
1034   GST_OBJECT_UNLOCK (buf);
1035
1036   return res;
1037
1038   /* ERRORS */
1039 flushing:
1040   {
1041     GST_DEBUG_OBJECT (buf, "we are flushing");
1042     GST_OBJECT_UNLOCK (buf);
1043     return FALSE;
1044   }
1045 not_acquired:
1046   {
1047     GST_DEBUG_OBJECT (buf, "not acquired");
1048     GST_OBJECT_UNLOCK (buf);
1049     return FALSE;
1050   }
1051 }
1052
1053 /**
1054  * gst_audio_ring_buffer_stop:
1055  * @buf: the #GstAudioRingBuffer to stop
1056  *
1057  * Stop processing samples from the ringbuffer.
1058  *
1059  * Returns: TRUE if the device could be stopped, FALSE on error.
1060  *
1061  * MT safe.
1062  */
1063 gboolean
1064 gst_audio_ring_buffer_stop (GstAudioRingBuffer * buf)
1065 {
1066   gboolean res = FALSE;
1067   GstAudioRingBufferClass *rclass;
1068
1069   g_return_val_if_fail (GST_IS_AUDIO_RING_BUFFER (buf), FALSE);
1070
1071   GST_DEBUG_OBJECT (buf, "stopping");
1072
1073   GST_OBJECT_LOCK (buf);
1074
1075   /* if started, set to stopped */
1076   res = g_atomic_int_compare_and_exchange (&buf->state,
1077       GST_AUDIO_RING_BUFFER_STATE_STARTED, GST_AUDIO_RING_BUFFER_STATE_STOPPED);
1078
1079   if (!res) {
1080     GST_DEBUG_OBJECT (buf, "was not started, try paused");
1081     /* was not started, try from paused */
1082     res = g_atomic_int_compare_and_exchange (&buf->state,
1083         GST_AUDIO_RING_BUFFER_STATE_PAUSED,
1084         GST_AUDIO_RING_BUFFER_STATE_STOPPED);
1085     if (!res) {
1086       /* was not paused either, must have been stopped then */
1087       res = TRUE;
1088       GST_DEBUG_OBJECT (buf, "was not paused, must have been stopped");
1089       goto done;
1090     }
1091   }
1092
1093   /* signal any waiters */
1094   GST_DEBUG_OBJECT (buf, "signal waiter");
1095   GST_AUDIO_RING_BUFFER_SIGNAL (buf);
1096
1097   rclass = GST_AUDIO_RING_BUFFER_GET_CLASS (buf);
1098   if (G_LIKELY (rclass->stop))
1099     res = rclass->stop (buf);
1100
1101   if (G_UNLIKELY (!res)) {
1102     buf->state = GST_AUDIO_RING_BUFFER_STATE_STARTED;
1103     GST_DEBUG_OBJECT (buf, "failed to stop");
1104   } else {
1105     GST_DEBUG_OBJECT (buf, "stopped");
1106   }
1107 done:
1108   GST_OBJECT_UNLOCK (buf);
1109
1110   return res;
1111 }
1112
1113 /**
1114  * gst_audio_ring_buffer_delay:
1115  * @buf: the #GstAudioRingBuffer to query
1116  *
1117  * Get the number of samples queued in the audio device. This is
1118  * usually less than the segment size but can be bigger when the
1119  * implementation uses another internal buffer between the audio
1120  * device.
1121  *
1122  * For playback ringbuffers this is the amount of samples transfered from the
1123  * ringbuffer to the device but still not played.
1124  *
1125  * For capture ringbuffers this is the amount of samples in the device that are
1126  * not yet transfered to the ringbuffer.
1127  *
1128  * Returns: The number of samples queued in the audio device.
1129  *
1130  * MT safe.
1131  */
1132 guint
1133 gst_audio_ring_buffer_delay (GstAudioRingBuffer * buf)
1134 {
1135   GstAudioRingBufferClass *rclass;
1136   guint res;
1137
1138   g_return_val_if_fail (GST_IS_AUDIO_RING_BUFFER (buf), 0);
1139
1140   /* buffer must be acquired */
1141   if (G_UNLIKELY (!gst_audio_ring_buffer_is_acquired (buf)))
1142     goto not_acquired;
1143
1144   rclass = GST_AUDIO_RING_BUFFER_GET_CLASS (buf);
1145   if (G_LIKELY (rclass->delay))
1146     res = rclass->delay (buf);
1147   else
1148     res = 0;
1149
1150   return res;
1151
1152 not_acquired:
1153   {
1154     GST_DEBUG_OBJECT (buf, "not acquired");
1155     return 0;
1156   }
1157 }
1158
1159 /**
1160  * gst_audio_ring_buffer_samples_done:
1161  * @buf: the #GstAudioRingBuffer to query
1162  *
1163  * Get the number of samples that were processed by the ringbuffer
1164  * since it was last started. This does not include the number of samples not
1165  * yet processed (see gst_audio_ring_buffer_delay()).
1166  *
1167  * Returns: The number of samples processed by the ringbuffer.
1168  *
1169  * MT safe.
1170  */
1171 guint64
1172 gst_audio_ring_buffer_samples_done (GstAudioRingBuffer * buf)
1173 {
1174   gint segdone;
1175   guint64 samples;
1176
1177   g_return_val_if_fail (GST_IS_AUDIO_RING_BUFFER (buf), 0);
1178
1179   /* get the amount of segments we processed */
1180   segdone = g_atomic_int_get (&buf->segdone);
1181
1182   /* convert to samples */
1183   samples = ((guint64) segdone) * buf->samples_per_seg;
1184
1185   return samples;
1186 }
1187
1188 /**
1189  * gst_audio_ring_buffer_set_sample:
1190  * @buf: the #GstAudioRingBuffer to use
1191  * @sample: the sample number to set
1192  *
1193  * Make sure that the next sample written to the device is
1194  * accounted for as being the @sample sample written to the
1195  * device. This value will be used in reporting the current
1196  * sample position of the ringbuffer.
1197  *
1198  * This function will also clear the buffer with silence.
1199  *
1200  * MT safe.
1201  */
1202 void
1203 gst_audio_ring_buffer_set_sample (GstAudioRingBuffer * buf, guint64 sample)
1204 {
1205   g_return_if_fail (GST_IS_AUDIO_RING_BUFFER (buf));
1206
1207   if (sample == -1)
1208     sample = 0;
1209
1210   if (G_UNLIKELY (buf->samples_per_seg == 0))
1211     return;
1212
1213   /* FIXME, we assume the ringbuffer can restart at a random 
1214    * position, round down to the beginning and keep track of
1215    * offset when calculating the processed samples. */
1216   buf->segbase = buf->segdone - sample / buf->samples_per_seg;
1217
1218   gst_audio_ring_buffer_clear_all (buf);
1219
1220   GST_DEBUG_OBJECT (buf, "set sample to %" G_GUINT64_FORMAT ", segbase %d",
1221       sample, buf->segbase);
1222 }
1223
1224 static void
1225 default_clear_all (GstAudioRingBuffer * buf)
1226 {
1227   gint i;
1228
1229   /* not fatal, we just are not negotiated yet */
1230   if (G_UNLIKELY (buf->spec.segtotal <= 0))
1231     return;
1232
1233   GST_DEBUG_OBJECT (buf, "clear all segments");
1234
1235   for (i = 0; i < buf->spec.segtotal; i++) {
1236     gst_audio_ring_buffer_clear (buf, i);
1237   }
1238 }
1239
1240 /**
1241  * gst_audio_ring_buffer_clear_all:
1242  * @buf: the #GstAudioRingBuffer to clear
1243  *
1244  * Fill the ringbuffer with silence.
1245  *
1246  * MT safe.
1247  */
1248 void
1249 gst_audio_ring_buffer_clear_all (GstAudioRingBuffer * buf)
1250 {
1251   GstAudioRingBufferClass *rclass;
1252
1253   g_return_if_fail (GST_IS_AUDIO_RING_BUFFER (buf));
1254
1255   rclass = GST_AUDIO_RING_BUFFER_GET_CLASS (buf);
1256
1257   if (G_LIKELY (rclass->clear_all))
1258     rclass->clear_all (buf);
1259 }
1260
1261
1262 static gboolean
1263 wait_segment (GstAudioRingBuffer * buf)
1264 {
1265   gint segments;
1266   gboolean wait = TRUE;
1267
1268   /* buffer must be started now or we deadlock since nobody is reading */
1269   if (G_UNLIKELY (g_atomic_int_get (&buf->state) !=
1270           GST_AUDIO_RING_BUFFER_STATE_STARTED)) {
1271     /* see if we are allowed to start it */
1272     if (G_UNLIKELY (g_atomic_int_get (&buf->may_start) == FALSE))
1273       goto no_start;
1274
1275     GST_DEBUG_OBJECT (buf, "start!");
1276     segments = g_atomic_int_get (&buf->segdone);
1277     gst_audio_ring_buffer_start (buf);
1278
1279     /* After starting, the writer may have wrote segments already and then we
1280      * don't need to wait anymore */
1281     if (G_LIKELY (g_atomic_int_get (&buf->segdone) != segments))
1282       wait = FALSE;
1283   }
1284
1285   /* take lock first, then update our waiting flag */
1286   GST_OBJECT_LOCK (buf);
1287   if (G_UNLIKELY (buf->flushing))
1288     goto flushing;
1289
1290   if (G_UNLIKELY (g_atomic_int_get (&buf->state) !=
1291           GST_AUDIO_RING_BUFFER_STATE_STARTED))
1292     goto not_started;
1293
1294   if (G_LIKELY (wait)) {
1295     if (g_atomic_int_compare_and_exchange (&buf->waiting, 0, 1)) {
1296       GST_DEBUG_OBJECT (buf, "waiting..");
1297       GST_AUDIO_RING_BUFFER_WAIT (buf);
1298
1299       if (G_UNLIKELY (buf->flushing))
1300         goto flushing;
1301
1302       if (G_UNLIKELY (g_atomic_int_get (&buf->state) !=
1303               GST_AUDIO_RING_BUFFER_STATE_STARTED))
1304         goto not_started;
1305     }
1306   }
1307   GST_OBJECT_UNLOCK (buf);
1308
1309   return TRUE;
1310
1311   /* ERROR */
1312 not_started:
1313   {
1314     g_atomic_int_compare_and_exchange (&buf->waiting, 1, 0);
1315     GST_DEBUG_OBJECT (buf, "stopped processing");
1316     GST_OBJECT_UNLOCK (buf);
1317     return FALSE;
1318   }
1319 flushing:
1320   {
1321     g_atomic_int_compare_and_exchange (&buf->waiting, 1, 0);
1322     GST_DEBUG_OBJECT (buf, "flushing");
1323     GST_OBJECT_UNLOCK (buf);
1324     return FALSE;
1325   }
1326 no_start:
1327   {
1328     GST_DEBUG_OBJECT (buf, "not allowed to start");
1329     return FALSE;
1330   }
1331 }
1332
1333
1334
1335 #define REORDER_SAMPLE(d, s, l)                 \
1336 G_STMT_START {                                  \
1337   gint i;                                       \
1338   for (i = 0; i < channels; i++) {              \
1339     memcpy (d + reorder_map[i] * bps, s + i * bps, bps); \
1340   }                                             \
1341 } G_STMT_END
1342
1343 #define REORDER_SAMPLES(d, s, len)              \
1344 G_STMT_START {                                  \
1345   gint i, len_ = len / bpf;                     \
1346   guint8 *d_ = d, *s_ = s;                      \
1347   for (i = 0; i < len_; i++) {                  \
1348     REORDER_SAMPLE(d_, s_, bpf);                \
1349     d_ += bpf;                                  \
1350     s_ += bpf;                                  \
1351   }                                             \
1352 } G_STMT_END
1353
1354 #define FWD_SAMPLES(s,se,d,de,F)                \
1355 G_STMT_START {                                  \
1356   /* no rate conversion */                      \
1357   guint towrite = MIN (se + bpf - s, de - d);   \
1358   /* simple copy */                             \
1359   if (!skip)                                    \
1360     F (d, s, towrite);                          \
1361   in_samples -= towrite / bpf;                  \
1362   out_samples -= towrite / bpf;                 \
1363   s += towrite;                                 \
1364   GST_DEBUG ("copy %u bytes", towrite);         \
1365 } G_STMT_END
1366
1367 /* in_samples >= out_samples, rate > 1.0 */
1368 #define FWD_UP_SAMPLES(s,se,d,de,F)             \
1369 G_STMT_START {                                  \
1370   guint8 *sb = s, *db = d;                      \
1371   while (s <= se && d < de) {                   \
1372     if (!skip)                                  \
1373       F (d, s, bpf);                            \
1374     s += bpf;                                   \
1375     *accum += outr;                             \
1376     if ((*accum << 1) >= inr) {                 \
1377       *accum -= inr;                            \
1378       d += bpf;                                 \
1379     }                                           \
1380   }                                             \
1381   in_samples -= (s - sb)/bpf;                   \
1382   out_samples -= (d - db)/bpf;                  \
1383   GST_DEBUG ("fwd_up end %d/%d",*accum,*toprocess);     \
1384 } G_STMT_END
1385
1386 /* out_samples > in_samples, for rates smaller than 1.0 */
1387 #define FWD_DOWN_SAMPLES(s,se,d,de,F)           \
1388 G_STMT_START {                                  \
1389   guint8 *sb = s, *db = d;                      \
1390   while (s <= se && d < de) {                   \
1391     if (!skip)                                  \
1392       F (d, s, bpf);                            \
1393     d += bpf;                                   \
1394     *accum += inr;                              \
1395     if ((*accum << 1) >= outr) {                \
1396       *accum -= outr;                           \
1397       s += bpf;                                 \
1398     }                                           \
1399   }                                             \
1400   in_samples -= (s - sb)/bpf;                   \
1401   out_samples -= (d - db)/bpf;                  \
1402   GST_DEBUG ("fwd_down end %d/%d",*accum,*toprocess);   \
1403 } G_STMT_END
1404
1405 #define REV_UP_SAMPLES(s,se,d,de,F)             \
1406 G_STMT_START {                                  \
1407   guint8 *sb = se, *db = d;                     \
1408   while (s <= se && d < de) {                   \
1409     if (!skip)                                  \
1410       F (d, se, bpf);                           \
1411     se -= bpf;                                  \
1412     *accum += outr;                             \
1413     while (d < de && (*accum << 1) >= inr) {    \
1414       *accum -= inr;                            \
1415       d += bpf;                                 \
1416     }                                           \
1417   }                                             \
1418   in_samples -= (sb - se)/bpf;                  \
1419   out_samples -= (d - db)/bpf;                  \
1420   GST_DEBUG ("rev_up end %d/%d",*accum,*toprocess);     \
1421 } G_STMT_END
1422
1423 #define REV_DOWN_SAMPLES(s,se,d,de,F)           \
1424 G_STMT_START {                                  \
1425   guint8 *sb = se, *db = d;                     \
1426   while (s <= se && d < de) {                   \
1427     if (!skip)                                  \
1428       F (d, se, bpf);                           \
1429     d += bpf;                                   \
1430     *accum += inr;                              \
1431     while (s <= se && (*accum << 1) >= outr) {  \
1432       *accum -= outr;                           \
1433       se -= bpf;                                \
1434     }                                           \
1435   }                                             \
1436   in_samples -= (sb - se)/bpf;                  \
1437   out_samples -= (d - db)/bpf;                  \
1438   GST_DEBUG ("rev_down end %d/%d",*accum,*toprocess);   \
1439 } G_STMT_END
1440
1441 static guint
1442 default_commit (GstAudioRingBuffer * buf, guint64 * sample,
1443     guint8 * data, gint in_samples, gint out_samples, gint * accum)
1444 {
1445   gint segdone;
1446   gint segsize, segtotal, channels, bps, bpf, sps;
1447   guint8 *dest, *data_end;
1448   gint writeseg, sampleoff;
1449   gint *toprocess;
1450   gint inr, outr;
1451   gboolean reverse;
1452   gboolean need_reorder;
1453
1454   g_return_val_if_fail (buf->memory != NULL, -1);
1455   g_return_val_if_fail (data != NULL, -1);
1456
1457   need_reorder = buf->need_reorder;
1458
1459   channels = buf->spec.info.channels;
1460   dest = buf->memory;
1461   segsize = buf->spec.segsize;
1462   segtotal = buf->spec.segtotal;
1463   bpf = buf->spec.info.bpf;
1464   bps = bpf / channels;
1465   sps = buf->samples_per_seg;
1466
1467   reverse = out_samples < 0;
1468   out_samples = ABS (out_samples);
1469
1470   if (in_samples >= out_samples)
1471     toprocess = &in_samples;
1472   else
1473     toprocess = &out_samples;
1474
1475   inr = in_samples - 1;
1476   outr = out_samples - 1;
1477
1478   /* data_end points to the last sample we have to write, not past it. This is
1479    * needed to properly handle reverse playback: it points to the last sample. */
1480   data_end = data + (bpf * inr);
1481
1482   /* figure out the segment and the offset inside the segment where
1483    * the first sample should be written. */
1484   writeseg = *sample / sps;
1485   sampleoff = (*sample % sps) * bpf;
1486
1487   GST_DEBUG_OBJECT (buf, "write %d : %d", in_samples, out_samples);
1488
1489   /* write out all samples */
1490   while (*toprocess > 0) {
1491     gint avail;
1492     guint8 *d, *d_end;
1493     gint ws;
1494     gboolean skip;
1495
1496     while (TRUE) {
1497       gint diff;
1498
1499       /* get the currently processed segment */
1500       segdone = g_atomic_int_get (&buf->segdone) - buf->segbase;
1501
1502       /* see how far away it is from the write segment */
1503       diff = writeseg - segdone;
1504
1505       GST_DEBUG_OBJECT (buf,
1506           "pointer at %d, write to %d-%d, diff %d, segtotal %d, segsize %d, base %d",
1507           segdone, writeseg, sampleoff, diff, segtotal, segsize, buf->segbase);
1508
1509       /* segment too far ahead, writer too slow, we need to drop, hopefully UNLIKELY */
1510       if (G_UNLIKELY (diff < 0)) {
1511         /* we need to drop one segment at a time, pretend we wrote a segment. */
1512         skip = TRUE;
1513         break;
1514       }
1515
1516       /* write segment is within writable range, we can break the loop and
1517        * start writing the data. */
1518       if (diff < segtotal) {
1519         skip = FALSE;
1520         break;
1521       }
1522
1523       /* else we need to wait for the segment to become writable. */
1524       if (!wait_segment (buf))
1525         goto not_started;
1526     }
1527
1528     /* we can write now */
1529     ws = writeseg % segtotal;
1530     avail = MIN (segsize - sampleoff, bpf * out_samples);
1531
1532     d = dest + (ws * segsize) + sampleoff;
1533     d_end = d + avail;
1534     *sample += avail / bpf;
1535
1536     GST_DEBUG_OBJECT (buf, "write @%p seg %d, sps %d, off %d, avail %d",
1537         dest + ws * segsize, ws, sps, sampleoff, avail);
1538
1539     if (need_reorder) {
1540       gint *reorder_map = buf->channel_reorder_map;
1541
1542       if (G_LIKELY (inr == outr && !reverse)) {
1543         /* no rate conversion, simply copy samples */
1544         FWD_SAMPLES (data, data_end, d, d_end, REORDER_SAMPLES);
1545       } else if (!reverse) {
1546         if (inr >= outr)
1547           /* forward speed up */
1548           FWD_UP_SAMPLES (data, data_end, d, d_end, REORDER_SAMPLE);
1549         else
1550           /* forward slow down */
1551           FWD_DOWN_SAMPLES (data, data_end, d, d_end, REORDER_SAMPLE);
1552       } else {
1553         if (inr >= outr)
1554           /* reverse speed up */
1555           REV_UP_SAMPLES (data, data_end, d, d_end, REORDER_SAMPLE);
1556         else
1557           /* reverse slow down */
1558           REV_DOWN_SAMPLES (data, data_end, d, d_end, REORDER_SAMPLE);
1559       }
1560     } else {
1561       if (G_LIKELY (inr == outr && !reverse)) {
1562         /* no rate conversion, simply copy samples */
1563         FWD_SAMPLES (data, data_end, d, d_end, memcpy);
1564       } else if (!reverse) {
1565         if (inr >= outr)
1566           /* forward speed up */
1567           FWD_UP_SAMPLES (data, data_end, d, d_end, memcpy);
1568         else
1569           /* forward slow down */
1570           FWD_DOWN_SAMPLES (data, data_end, d, d_end, memcpy);
1571       } else {
1572         if (inr >= outr)
1573           /* reverse speed up */
1574           REV_UP_SAMPLES (data, data_end, d, d_end, memcpy);
1575         else
1576           /* reverse slow down */
1577           REV_DOWN_SAMPLES (data, data_end, d, d_end, memcpy);
1578       }
1579     }
1580
1581     /* for the next iteration we write to the next segment at the beginning. */
1582     writeseg++;
1583     sampleoff = 0;
1584   }
1585   /* we consumed all samples here */
1586   data = data_end + bpf;
1587
1588 done:
1589   return inr - ((data_end - data) / bpf);
1590
1591   /* ERRORS */
1592 not_started:
1593   {
1594     GST_DEBUG_OBJECT (buf, "stopped processing");
1595     goto done;
1596   }
1597 }
1598
1599 /**
1600  * gst_audio_ring_buffer_commit:
1601  * @buf: the #GstAudioRingBuffer to commit
1602  * @sample: the sample position of the data
1603  * @data: the data to commit
1604  * @in_samples: the number of samples in the data to commit
1605  * @out_samples: the number of samples to write to the ringbuffer
1606  * @accum: accumulator for rate conversion.
1607  *
1608  * Commit @in_samples samples pointed to by @data to the ringbuffer @buf.
1609  *
1610  * @in_samples and @out_samples define the rate conversion to perform on the
1611  * samples in @data. For negative rates, @out_samples must be negative and
1612  * @in_samples positive.
1613  *
1614  * When @out_samples is positive, the first sample will be written at position @sample
1615  * in the ringbuffer. When @out_samples is negative, the last sample will be written to
1616  * @sample in reverse order.
1617  *
1618  * @out_samples does not need to be a multiple of the segment size of the ringbuffer
1619  * although it is recommended for optimal performance.
1620  *
1621  * @accum will hold a temporary accumulator used in rate conversion and should be
1622  * set to 0 when this function is first called. In case the commit operation is
1623  * interrupted, one can resume the processing by passing the previously returned
1624  * @accum value back to this function.
1625  *
1626  * MT safe.
1627  *
1628  * Returns: The number of samples written to the ringbuffer or -1 on error. The
1629  * number of samples written can be less than @out_samples when @buf was interrupted
1630  * with a flush or stop.
1631  */
1632 guint
1633 gst_audio_ring_buffer_commit (GstAudioRingBuffer * buf, guint64 * sample,
1634     guint8 * data, gint in_samples, gint out_samples, gint * accum)
1635 {
1636   GstAudioRingBufferClass *rclass;
1637   guint res = -1;
1638
1639   g_return_val_if_fail (GST_IS_AUDIO_RING_BUFFER (buf), -1);
1640
1641   if (G_UNLIKELY (in_samples == 0 || out_samples == 0))
1642     return in_samples;
1643
1644   rclass = GST_AUDIO_RING_BUFFER_GET_CLASS (buf);
1645
1646   if (G_LIKELY (rclass->commit))
1647     res = rclass->commit (buf, sample, data, in_samples, out_samples, accum);
1648
1649   return res;
1650 }
1651
1652 /**
1653  * gst_audio_ring_buffer_read:
1654  * @buf: the #GstAudioRingBuffer to read from
1655  * @sample: the sample position of the data
1656  * @data: where the data should be read
1657  * @len: the number of samples in data to read
1658  * @timestamp: where the timestamp is returned
1659  *
1660  * Read @len samples from the ringbuffer into the memory pointed 
1661  * to by @data.
1662  * The first sample should be read from position @sample in
1663  * the ringbuffer.
1664  *
1665  * @len should not be a multiple of the segment size of the ringbuffer
1666  * although it is recommended.
1667  *
1668  * @timestamp will return the timestamp associated with the data returned.
1669  *
1670  * Returns: The number of samples read from the ringbuffer or -1 on
1671  * error.
1672  *
1673  * MT safe.
1674  */
1675 guint
1676 gst_audio_ring_buffer_read (GstAudioRingBuffer * buf, guint64 sample,
1677     guint8 * data, guint len, GstClockTime * timestamp)
1678 {
1679   gint segdone;
1680   gint segsize, segtotal, channels, bps, bpf, sps, readseg = 0;
1681   guint8 *dest;
1682   guint to_read;
1683   gboolean need_reorder;
1684
1685   g_return_val_if_fail (GST_IS_AUDIO_RING_BUFFER (buf), -1);
1686   g_return_val_if_fail (buf->memory != NULL, -1);
1687   g_return_val_if_fail (data != NULL, -1);
1688
1689   need_reorder = buf->need_reorder;
1690   dest = buf->memory;
1691   segsize = buf->spec.segsize;
1692   segtotal = buf->spec.segtotal;
1693   channels = buf->spec.info.channels;
1694   bpf = buf->spec.info.bpf;
1695   bps = bpf / channels;
1696   sps = buf->samples_per_seg;
1697
1698   to_read = len;
1699   /* read enough samples */
1700   while (to_read > 0) {
1701     gint sampleslen;
1702     gint sampleoff;
1703
1704     /* figure out the segment and the offset inside the segment where
1705      * the sample should be read from. */
1706     readseg = sample / sps;
1707     sampleoff = (sample % sps);
1708
1709     while (TRUE) {
1710       gint diff;
1711
1712       /* get the currently processed segment */
1713       segdone = g_atomic_int_get (&buf->segdone) - buf->segbase;
1714
1715       /* see how far away it is from the read segment, normally segdone (where
1716        * the hardware is writing) is bigger than readseg (where software is
1717        * reading) */
1718       diff = segdone - readseg;
1719
1720       GST_DEBUG
1721           ("pointer at %d, sample %" G_GUINT64_FORMAT
1722           ", read from %d-%d, to_read %d, diff %d, segtotal %d, segsize %d",
1723           segdone, sample, readseg, sampleoff, to_read, diff, segtotal,
1724           segsize);
1725
1726       /* segment too far ahead, reader too slow */
1727       if (G_UNLIKELY (diff >= segtotal)) {
1728         /* pretend we read an empty segment. */
1729         sampleslen = MIN (sps, to_read);
1730         memcpy (data, buf->empty_seg, sampleslen * bpf);
1731         goto next;
1732       }
1733
1734       /* read segment is within readable range, we can break the loop and
1735        * start reading the data. */
1736       if (diff > 0)
1737         break;
1738
1739       /* else we need to wait for the segment to become readable. */
1740       if (!wait_segment (buf))
1741         goto not_started;
1742     }
1743
1744     /* we can read now */
1745     readseg = readseg % segtotal;
1746     sampleslen = MIN (sps - sampleoff, to_read);
1747
1748     GST_DEBUG_OBJECT (buf, "read @%p seg %d, off %d, sampleslen %d",
1749         dest + readseg * segsize, readseg, sampleoff, sampleslen);
1750
1751     if (need_reorder) {
1752       guint8 *ptr = dest + (readseg * segsize) + (sampleoff * bpf);
1753       gint i, j;
1754       gint *reorder_map = buf->channel_reorder_map;
1755
1756       /* Reorder from device order to GStreamer order */
1757       for (i = 0; i < sampleslen; i++) {
1758         for (j = 0; j < channels; j++) {
1759           memcpy (data + reorder_map[j] * bps, ptr + j * bps, bps);
1760         }
1761         ptr += bpf;
1762       }
1763     } else {
1764       memcpy (data, dest + (readseg * segsize) + (sampleoff * bpf),
1765           (sampleslen * bpf));
1766     }
1767
1768   next:
1769     to_read -= sampleslen;
1770     sample += sampleslen;
1771     data += sampleslen * bpf;
1772   }
1773
1774   if (buf->timestamps && timestamp) {
1775     *timestamp = buf->timestamps[readseg % segtotal];
1776     GST_INFO_OBJECT (buf, "Retrieved timestamp %" GST_TIME_FORMAT
1777         " @ %d", GST_TIME_ARGS (*timestamp), readseg % segtotal);
1778   }
1779
1780   return len - to_read;
1781
1782   /* ERRORS */
1783 not_started:
1784   {
1785     GST_DEBUG_OBJECT (buf, "stopped processing");
1786     return len - to_read;
1787   }
1788 }
1789
1790 /**
1791  * gst_audio_ring_buffer_prepare_read:
1792  * @buf: the #GstAudioRingBuffer to read from
1793  * @segment: the segment to read
1794  * @readptr: the pointer to the memory where samples can be read
1795  * @len: the number of bytes to read
1796  *
1797  * Returns a pointer to memory where the data from segment @segment
1798  * can be found. This function is mostly used by subclasses.
1799  *
1800  * Returns: FALSE if the buffer is not started.
1801  *
1802  * MT safe.
1803  */
1804 gboolean
1805 gst_audio_ring_buffer_prepare_read (GstAudioRingBuffer * buf, gint * segment,
1806     guint8 ** readptr, gint * len)
1807 {
1808   guint8 *data;
1809   gint segdone;
1810
1811   g_return_val_if_fail (GST_IS_AUDIO_RING_BUFFER (buf), FALSE);
1812
1813   if (buf->callback == NULL) {
1814     /* push mode, fail when nothing is started */
1815     if (g_atomic_int_get (&buf->state) != GST_AUDIO_RING_BUFFER_STATE_STARTED)
1816       return FALSE;
1817   }
1818
1819   g_return_val_if_fail (buf->memory != NULL, FALSE);
1820   g_return_val_if_fail (segment != NULL, FALSE);
1821   g_return_val_if_fail (readptr != NULL, FALSE);
1822   g_return_val_if_fail (len != NULL, FALSE);
1823
1824   data = buf->memory;
1825
1826   /* get the position of the pointer */
1827   segdone = g_atomic_int_get (&buf->segdone);
1828
1829   *segment = segdone % buf->spec.segtotal;
1830   *len = buf->spec.segsize;
1831   *readptr = data + *segment * *len;
1832
1833   GST_LOG ("prepare read from segment %d (real %d) @%p",
1834       *segment, segdone, *readptr);
1835
1836   /* callback to fill the memory with data, for pull based
1837    * scheduling. */
1838   if (buf->callback)
1839     buf->callback (buf, *readptr, *len, buf->cb_data);
1840
1841   return TRUE;
1842 }
1843
1844 /**
1845  * gst_audio_ring_buffer_advance:
1846  * @buf: the #GstAudioRingBuffer to advance
1847  * @advance: the number of segments written
1848  *
1849  * Subclasses should call this function to notify the fact that 
1850  * @advance segments are now processed by the device.
1851  *
1852  * MT safe.
1853  */
1854 void
1855 gst_audio_ring_buffer_advance (GstAudioRingBuffer * buf, guint advance)
1856 {
1857   g_return_if_fail (GST_IS_AUDIO_RING_BUFFER (buf));
1858
1859   /* update counter */
1860   g_atomic_int_add (&buf->segdone, advance);
1861
1862   /* the lock is already taken when the waiting flag is set,
1863    * we grab the lock as well to make sure the waiter is actually
1864    * waiting for the signal */
1865   if (g_atomic_int_compare_and_exchange (&buf->waiting, 1, 0)) {
1866     GST_OBJECT_LOCK (buf);
1867     GST_DEBUG_OBJECT (buf, "signal waiter");
1868     GST_AUDIO_RING_BUFFER_SIGNAL (buf);
1869     GST_OBJECT_UNLOCK (buf);
1870   }
1871 }
1872
1873 /**
1874  * gst_audio_ring_buffer_clear:
1875  * @buf: the #GstAudioRingBuffer to clear
1876  * @segment: the segment to clear
1877  *
1878  * Clear the given segment of the buffer with silence samples.
1879  * This function is used by subclasses.
1880  *
1881  * MT safe.
1882  */
1883 void
1884 gst_audio_ring_buffer_clear (GstAudioRingBuffer * buf, gint segment)
1885 {
1886   guint8 *data;
1887
1888   g_return_if_fail (GST_IS_AUDIO_RING_BUFFER (buf));
1889
1890   /* no data means it's already cleared */
1891   if (G_UNLIKELY (buf->memory == NULL))
1892     return;
1893
1894   /* no empty_seg means it's not opened */
1895   if (G_UNLIKELY (buf->empty_seg == NULL))
1896     return;
1897
1898   segment %= buf->spec.segtotal;
1899
1900   data = buf->memory;
1901   data += segment * buf->spec.segsize;
1902
1903   GST_LOG ("clear segment %d @%p", segment, data);
1904
1905   memcpy (data, buf->empty_seg, buf->spec.segsize);
1906 }
1907
1908 /**
1909  * gst_audio_ring_buffer_may_start:
1910  * @buf: the #GstAudioRingBuffer
1911  * @allowed: the new value
1912  *
1913  * Tell the ringbuffer that it is allowed to start playback when
1914  * the ringbuffer is filled with samples. 
1915  *
1916  * MT safe.
1917  */
1918 void
1919 gst_audio_ring_buffer_may_start (GstAudioRingBuffer * buf, gboolean allowed)
1920 {
1921   g_return_if_fail (GST_IS_AUDIO_RING_BUFFER (buf));
1922
1923   GST_LOG_OBJECT (buf, "may start: %d", allowed);
1924   g_atomic_int_set (&buf->may_start, allowed);
1925 }
1926
1927 /**
1928  * gst_audio_ring_buffer_set_channel_positions:
1929  * @buf: the #GstAudioRingBuffer
1930  * @position: the device channel positions
1931  *
1932  * Tell the ringbuffer about the device's channel positions. This must
1933  * be called in when the ringbuffer is acquired.
1934  */
1935 void
1936 gst_audio_ring_buffer_set_channel_positions (GstAudioRingBuffer * buf,
1937     const GstAudioChannelPosition * position)
1938 {
1939   const GstAudioChannelPosition *to;
1940   gint channels;
1941   gint i;
1942
1943   g_return_if_fail (GST_IS_AUDIO_RING_BUFFER (buf));
1944   g_return_if_fail (buf->acquired);
1945
1946   channels = buf->spec.info.channels;
1947   to = buf->spec.info.position;
1948
1949   buf->need_reorder = FALSE;
1950   if (memcmp (position, to, channels * sizeof (to[0])) == 0)
1951     return;
1952
1953   if (!gst_audio_get_channel_reorder_map (channels, position, to,
1954           buf->channel_reorder_map))
1955     g_return_if_reached ();
1956
1957   for (i = 0; i < channels; i++) {
1958     if (buf->channel_reorder_map[i] != i) {
1959       buf->need_reorder = TRUE;
1960       break;
1961     }
1962   }
1963 }
1964
1965 /**
1966  * gst_ring_buffer_set_timestamp:
1967  * @buf: the #GstRingBuffer
1968  * @readseg: the current data segment
1969  * @timestamp: The new timestamp of the buffer.
1970  *
1971  * Set a new timestamp on the buffer.
1972  *
1973  * MT safe.
1974  */
1975 void
1976 gst_audio_ring_buffer_set_timestamp (GstAudioRingBuffer * buf, gint readseg,
1977     GstClockTime timestamp)
1978 {
1979   g_return_if_fail (GST_IS_AUDIO_RING_BUFFER (buf));
1980
1981   GST_INFO_OBJECT (buf, "Storing timestamp %" GST_TIME_FORMAT
1982       " @ %d", GST_TIME_ARGS (timestamp), readseg);
1983   if (buf->timestamps) {
1984     buf->timestamps[readseg] = timestamp;
1985   } else {
1986     GST_ERROR_OBJECT (buf, "Could not store timestamp, no timestamps buffer");
1987   }
1988 }