2 * Copyright (C) 2005 Wim Taymans <wim@fluendo.com>
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.
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.
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., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
21 * SECTION:gstaudioringbuffer
22 * @short_description: Base class for audio ringbuffer implementations
23 * @see_also: #GstAudioBaseSink, #GstAudioSink
27 * This object is the base class for audio ringbuffers used by the base
28 * audio source and sink classes.
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
39 * Last reviewed on 2006-02-02 (0.10.4)
44 #include "gstaudioringbuffer.h"
46 GST_DEBUG_CATEGORY_STATIC (gst_audio_ring_buffer_debug);
47 #define GST_CAT_DEFAULT gst_audio_ring_buffer_debug
49 static void gst_audio_ring_buffer_dispose (GObject * object);
50 static void gst_audio_ring_buffer_finalize (GObject * object);
52 static gboolean gst_audio_ring_buffer_pause_unlocked (GstAudioRingBuffer * buf);
53 static void default_clear_all (GstAudioRingBuffer * buf);
54 static guint default_commit (GstAudioRingBuffer * buf, guint64 * sample,
55 guint8 * data, gint in_samples, gint out_samples, gint * accum);
57 /* ringbuffer abstract base class */
58 G_DEFINE_ABSTRACT_TYPE (GstAudioRingBuffer, gst_audio_ring_buffer,
62 gst_audio_ring_buffer_class_init (GstAudioRingBufferClass * klass)
64 GObjectClass *gobject_class;
65 GstAudioRingBufferClass *gstaudioringbuffer_class;
67 gobject_class = (GObjectClass *) klass;
68 gstaudioringbuffer_class = (GstAudioRingBufferClass *) klass;
70 GST_DEBUG_CATEGORY_INIT (gst_audio_ring_buffer_debug, "ringbuffer", 0,
73 gobject_class->dispose = gst_audio_ring_buffer_dispose;
74 gobject_class->finalize = gst_audio_ring_buffer_finalize;
76 gstaudioringbuffer_class->clear_all = GST_DEBUG_FUNCPTR (default_clear_all);
77 gstaudioringbuffer_class->commit = GST_DEBUG_FUNCPTR (default_commit);
81 gst_audio_ring_buffer_init (GstAudioRingBuffer * ringbuffer)
83 ringbuffer->open = FALSE;
84 ringbuffer->acquired = FALSE;
85 ringbuffer->state = GST_AUDIO_RING_BUFFER_STATE_STOPPED;
86 g_cond_init (&ringbuffer->cond);
87 ringbuffer->waiting = 0;
88 ringbuffer->empty_seg = NULL;
89 ringbuffer->flushing = TRUE;
93 gst_audio_ring_buffer_dispose (GObject * object)
95 GstAudioRingBuffer *ringbuffer = GST_AUDIO_RING_BUFFER (object);
97 gst_caps_replace (&ringbuffer->spec.caps, NULL);
99 G_OBJECT_CLASS (gst_audio_ring_buffer_parent_class)->dispose (G_OBJECT
104 gst_audio_ring_buffer_finalize (GObject * object)
106 GstAudioRingBuffer *ringbuffer = GST_AUDIO_RING_BUFFER (object);
108 g_cond_clear (&ringbuffer->cond);
109 g_free (ringbuffer->empty_seg);
111 G_OBJECT_CLASS (gst_audio_ring_buffer_parent_class)->finalize (G_OBJECT
115 #ifndef GST_DISABLE_GST_DEBUG
116 static const gchar *format_type_names[] = {
131 * gst_audio_ring_buffer_debug_spec_caps:
132 * @spec: the spec to debug
134 * Print debug info about the parsed caps in @spec to the debug log.
137 gst_audio_ring_buffer_debug_spec_caps (GstAudioRingBufferSpec * spec)
143 GST_DEBUG ("spec caps: %p %" GST_PTR_FORMAT, spec->caps, spec->caps);
144 GST_DEBUG ("parsed caps: type: %d, '%s'", spec->type,
145 format_type_names[spec->type]);
147 GST_DEBUG ("parsed caps: width: %d", spec->width);
148 GST_DEBUG ("parsed caps: sign: %d", spec->sign);
149 GST_DEBUG ("parsed caps: bigend: %d", spec->bigend);
150 GST_DEBUG ("parsed caps: rate: %d", spec->rate);
151 GST_DEBUG ("parsed caps: channels: %d", spec->channels);
152 GST_DEBUG ("parsed caps: sample bytes: %d", spec->bytes_per_sample);
153 bytes = (spec->width >> 3) * spec->channels;
154 for (i = 0; i < bytes; i++) {
155 GST_DEBUG ("silence byte %d: %02x", i, spec->silence_sample[i]);
161 * gst_audio_ring_buffer_debug_spec_buff:
162 * @spec: the spec to debug
164 * Print debug info about the buffer sized in @spec to the debug log.
167 gst_audio_ring_buffer_debug_spec_buff (GstAudioRingBufferSpec * spec)
169 gint bpf = GST_AUDIO_INFO_BPF (&spec->info);
171 GST_DEBUG ("acquire ringbuffer: buffer time: %" G_GINT64_FORMAT " usec",
173 GST_DEBUG ("acquire ringbuffer: latency time: %" G_GINT64_FORMAT " usec",
175 GST_DEBUG ("acquire ringbuffer: total segments: %d", spec->segtotal);
176 GST_DEBUG ("acquire ringbuffer: latency segments: %d", spec->seglatency);
177 GST_DEBUG ("acquire ringbuffer: segment size: %d bytes = %d samples",
178 spec->segsize, spec->segsize / bpf);
179 GST_DEBUG ("acquire ringbuffer: buffer size: %d bytes = %d samples",
180 spec->segsize * spec->segtotal, spec->segsize * spec->segtotal / bpf);
184 * gst_audio_ring_buffer_parse_caps:
188 * Parse @caps into @spec.
190 * Returns: TRUE if the caps could be parsed.
193 gst_audio_ring_buffer_parse_caps (GstAudioRingBufferSpec * spec, GstCaps * caps)
195 const gchar *mimetype;
196 GstStructure *structure;
200 structure = gst_caps_get_structure (caps, 0);
201 gst_audio_info_init (&info);
203 /* we have to differentiate between int and float formats */
204 mimetype = gst_structure_get_name (structure);
206 if (g_str_equal (mimetype, "audio/x-raw")) {
207 if (!gst_audio_info_from_caps (&info, caps))
210 spec->type = GST_AUDIO_RING_BUFFER_FORMAT_TYPE_RAW;
211 } else if (g_str_equal (mimetype, "audio/x-alaw")) {
212 /* extract the needed information from the cap */
213 if (!(gst_structure_get_int (structure, "rate", &info.rate) &&
214 gst_structure_get_int (structure, "channels", &info.channels)))
217 spec->type = GST_AUDIO_RING_BUFFER_FORMAT_TYPE_A_LAW;
218 info.bpf = info.channels;
219 } else if (g_str_equal (mimetype, "audio/x-mulaw")) {
220 /* extract the needed information from the cap */
221 if (!(gst_structure_get_int (structure, "rate", &info.rate) &&
222 gst_structure_get_int (structure, "channels", &info.channels)))
225 spec->type = GST_AUDIO_RING_BUFFER_FORMAT_TYPE_MU_LAW;
226 info.bpf = info.channels;
227 } else if (g_str_equal (mimetype, "audio/x-iec958")) {
228 /* extract the needed information from the cap */
229 if (!(gst_structure_get_int (structure, "rate", &info.rate)))
232 spec->type = GST_AUDIO_RING_BUFFER_FORMAT_TYPE_IEC958;
234 } else if (g_str_equal (mimetype, "audio/x-ac3")) {
235 /* extract the needed information from the cap */
236 if (!(gst_structure_get_int (structure, "rate", &info.rate)))
239 spec->type = GST_AUDIO_RING_BUFFER_FORMAT_TYPE_AC3;
241 } else if (g_str_equal (mimetype, "audio/x-eac3")) {
242 /* extract the needed information from the cap */
243 if (!(gst_structure_get_int (structure, "rate", &info.rate)))
246 spec->type = GST_AUDIO_RING_BUFFER_FORMAT_TYPE_EAC3;
248 } else if (g_str_equal (mimetype, "audio/x-dts")) {
249 /* extract the needed information from the cap */
250 if (!(gst_structure_get_int (structure, "rate", &info.rate)))
253 spec->type = GST_AUDIO_RING_BUFFER_FORMAT_TYPE_DTS;
255 } else if (g_str_equal (mimetype, "audio/mpeg") &&
256 gst_structure_get_int (structure, "mpegaudioversion", &i) &&
257 (i == 1 || i == 2)) {
258 /* Now we know this is MPEG-1 or MPEG-2 (non AAC) */
259 /* extract the needed information from the cap */
260 if (!(gst_structure_get_int (structure, "rate", &info.rate)))
263 spec->type = GST_AUDIO_RING_BUFFER_FORMAT_TYPE_MPEG;
269 gst_caps_replace (&spec->caps, caps);
271 g_return_val_if_fail (spec->latency_time != 0, FALSE);
273 /* calculate suggested segsize and segtotal. segsize should be one unit
274 * of 'latency_time' samples, scaling for the fact that latency_time is
275 * currently stored in microseconds (FIXME: in 0.11) */
276 spec->segsize = gst_util_uint64_scale (info.rate * info.bpf,
277 spec->latency_time, GST_SECOND / GST_USECOND);
278 /* Round to an integer number of samples */
279 spec->segsize -= spec->segsize % info.bpf;
281 spec->segtotal = spec->buffer_time / spec->latency_time;
282 /* leave the latency undefined now, implementations can change it but if it's
283 * not changed, we assume the same value as segtotal */
284 spec->seglatency = -1;
288 gst_audio_ring_buffer_debug_spec_caps (spec);
289 gst_audio_ring_buffer_debug_spec_buff (spec);
296 GST_DEBUG ("could not parse caps");
302 * gst_audio_ring_buffer_convert:
303 * @buf: the #GstAudioRingBuffer
304 * @src_fmt: the source format
305 * @src_val: the source value
306 * @dest_fmt: the destination format
307 * @dest_val: a location to store the converted value
309 * Convert @src_val in @src_fmt to the equivalent value in @dest_fmt. The result
310 * will be put in @dest_val.
312 * Returns: TRUE if the conversion succeeded.
315 gst_audio_ring_buffer_convert (GstAudioRingBuffer * buf,
316 GstFormat src_fmt, gint64 src_val, GstFormat dest_fmt, gint64 * dest_val)
320 GST_OBJECT_LOCK (buf);
322 gst_audio_info_convert (&buf->spec.info, src_fmt, src_val, dest_fmt,
324 GST_OBJECT_UNLOCK (buf);
330 * gst_audio_ring_buffer_set_callback:
331 * @buf: the #GstAudioRingBuffer to set the callback on
332 * @cb: (scope async): the callback to set
333 * @user_data: user data passed to the callback
335 * Sets the given callback function on the buffer. This function
336 * will be called every time a segment has been written to a device.
341 gst_audio_ring_buffer_set_callback (GstAudioRingBuffer * buf,
342 GstAudioRingBufferCallback cb, gpointer user_data)
344 g_return_if_fail (GST_IS_AUDIO_RING_BUFFER (buf));
346 GST_OBJECT_LOCK (buf);
348 buf->cb_data = user_data;
349 GST_OBJECT_UNLOCK (buf);
354 * gst_audio_ring_buffer_open_device:
355 * @buf: the #GstAudioRingBuffer
357 * Open the audio device associated with the ring buffer. Does not perform any
358 * setup on the device. You must open the device before acquiring the ring
361 * Returns: TRUE if the device could be opened, FALSE on error.
366 gst_audio_ring_buffer_open_device (GstAudioRingBuffer * buf)
369 GstAudioRingBufferClass *rclass;
371 g_return_val_if_fail (GST_IS_AUDIO_RING_BUFFER (buf), FALSE);
373 GST_DEBUG_OBJECT (buf, "opening device");
375 GST_OBJECT_LOCK (buf);
376 if (G_UNLIKELY (buf->open))
381 /* if this fails, something is wrong in this file */
382 g_assert (!buf->acquired);
384 rclass = GST_AUDIO_RING_BUFFER_GET_CLASS (buf);
385 if (G_LIKELY (rclass->open_device))
386 res = rclass->open_device (buf);
388 if (G_UNLIKELY (!res))
391 GST_DEBUG_OBJECT (buf, "opened device");
394 GST_OBJECT_UNLOCK (buf);
401 GST_DEBUG_OBJECT (buf, "Device for ring buffer already open");
402 g_warning ("Device for ring buffer %p already open, fix your code", buf);
409 GST_DEBUG_OBJECT (buf, "failed opening device");
415 * gst_audio_ring_buffer_close_device:
416 * @buf: the #GstAudioRingBuffer
418 * Close the audio device associated with the ring buffer. The ring buffer
419 * should already have been released via gst_audio_ring_buffer_release().
421 * Returns: TRUE if the device could be closed, FALSE on error.
426 gst_audio_ring_buffer_close_device (GstAudioRingBuffer * buf)
429 GstAudioRingBufferClass *rclass;
431 g_return_val_if_fail (GST_IS_AUDIO_RING_BUFFER (buf), FALSE);
433 GST_DEBUG_OBJECT (buf, "closing device");
435 GST_OBJECT_LOCK (buf);
436 if (G_UNLIKELY (!buf->open))
439 if (G_UNLIKELY (buf->acquired))
444 rclass = GST_AUDIO_RING_BUFFER_GET_CLASS (buf);
445 if (G_LIKELY (rclass->close_device))
446 res = rclass->close_device (buf);
448 if (G_UNLIKELY (!res))
451 GST_DEBUG_OBJECT (buf, "closed device");
454 GST_OBJECT_UNLOCK (buf);
461 GST_DEBUG_OBJECT (buf, "Device for ring buffer already closed");
462 g_warning ("Device for ring buffer %p already closed, fix your code", buf);
468 GST_DEBUG_OBJECT (buf, "Resources for ring buffer still acquired");
469 g_critical ("Resources for ring buffer %p still acquired", buf);
476 GST_DEBUG_OBJECT (buf, "error closing device");
482 * gst_audio_ring_buffer_device_is_open:
483 * @buf: the #GstAudioRingBuffer
485 * Checks the status of the device associated with the ring buffer.
487 * Returns: TRUE if the device was open, FALSE if it was closed.
492 gst_audio_ring_buffer_device_is_open (GstAudioRingBuffer * buf)
496 g_return_val_if_fail (GST_IS_AUDIO_RING_BUFFER (buf), FALSE);
498 GST_OBJECT_LOCK (buf);
500 GST_OBJECT_UNLOCK (buf);
506 * gst_audio_ring_buffer_acquire:
507 * @buf: the #GstAudioRingBuffer to acquire
508 * @spec: the specs of the buffer
510 * Allocate the resources for the ringbuffer. This function fills
511 * in the data pointer of the ring buffer with a valid #GstBuffer
512 * to which samples can be written.
514 * Returns: TRUE if the device could be acquired, FALSE on error.
519 gst_audio_ring_buffer_acquire (GstAudioRingBuffer * buf,
520 GstAudioRingBufferSpec * spec)
522 gboolean res = FALSE;
523 GstAudioRingBufferClass *rclass;
524 gint segsize, bpf, i;
526 g_return_val_if_fail (GST_IS_AUDIO_RING_BUFFER (buf), FALSE);
528 GST_DEBUG_OBJECT (buf, "acquiring device %p", buf);
530 GST_OBJECT_LOCK (buf);
531 if (G_UNLIKELY (!buf->open))
534 if (G_UNLIKELY (buf->acquired))
537 buf->acquired = TRUE;
538 buf->need_reorder = FALSE;
540 rclass = GST_AUDIO_RING_BUFFER_GET_CLASS (buf);
541 if (G_LIKELY (rclass->acquire))
542 res = rclass->acquire (buf, spec);
544 /* Only reorder for raw audio */
545 buf->need_reorder = (buf->need_reorder
546 && buf->spec.type == GST_AUDIO_RING_BUFFER_FORMAT_TYPE_RAW);
548 if (G_UNLIKELY (!res))
551 GST_INFO_OBJECT (buf, "Allocating an array for %d timestamps",
553 buf->timestamps = g_slice_alloc0 (sizeof (GstClockTime) * spec->segtotal);
554 /* initialize array with invalid timestamps */
555 for (i = 0; i < spec->segtotal; i++) {
556 buf->timestamps[i] = GST_CLOCK_TIME_NONE;
559 if (G_UNLIKELY ((bpf = buf->spec.info.bpf) == 0))
562 /* if the seglatency was overwritten with something else than -1, use it, else
563 * assume segtotal as the latency */
564 if (buf->spec.seglatency == -1)
565 buf->spec.seglatency = buf->spec.segtotal;
567 segsize = buf->spec.segsize;
569 buf->samples_per_seg = segsize / bpf;
571 /* create an empty segment */
572 g_free (buf->empty_seg);
573 buf->empty_seg = g_malloc (segsize);
575 if (buf->spec.type == GST_AUDIO_RING_BUFFER_FORMAT_TYPE_RAW) {
576 gst_audio_format_fill_silence (buf->spec.info.finfo, buf->empty_seg,
579 /* FIXME, non-raw formats get 0 as the empty sample */
580 memset (buf->empty_seg, 0, segsize);
582 GST_DEBUG_OBJECT (buf, "acquired device");
585 GST_OBJECT_UNLOCK (buf);
592 GST_DEBUG_OBJECT (buf, "device not opened");
593 g_critical ("Device for %p not opened", buf);
600 GST_DEBUG_OBJECT (buf, "device was acquired");
605 buf->acquired = FALSE;
606 GST_DEBUG_OBJECT (buf, "failed to acquire device");
612 ("invalid bytes_per_frame from acquire ringbuffer %p, fix the element",
614 buf->acquired = FALSE;
621 * gst_audio_ring_buffer_release:
622 * @buf: the #GstAudioRingBuffer to release
624 * Free the resources of the ringbuffer.
626 * Returns: TRUE if the device could be released, FALSE on error.
631 gst_audio_ring_buffer_release (GstAudioRingBuffer * buf)
633 gboolean res = FALSE;
634 GstAudioRingBufferClass *rclass;
636 g_return_val_if_fail (GST_IS_AUDIO_RING_BUFFER (buf), FALSE);
638 GST_DEBUG_OBJECT (buf, "releasing device");
640 gst_audio_ring_buffer_stop (buf);
642 GST_OBJECT_LOCK (buf);
644 if (G_LIKELY (buf->timestamps)) {
645 GST_INFO_OBJECT (buf, "Freeing timestamp buffer, %d entries",
647 g_slice_free1 (sizeof (GstClockTime) * buf->spec.segtotal, buf->timestamps);
648 buf->timestamps = NULL;
651 if (G_UNLIKELY (!buf->acquired))
654 buf->acquired = FALSE;
656 /* if this fails, something is wrong in this file */
657 g_assert (buf->open == TRUE);
659 rclass = GST_AUDIO_RING_BUFFER_GET_CLASS (buf);
660 if (G_LIKELY (rclass->release))
661 res = rclass->release (buf);
663 /* signal any waiters */
664 GST_DEBUG_OBJECT (buf, "signal waiter");
665 GST_AUDIO_RING_BUFFER_SIGNAL (buf);
667 if (G_UNLIKELY (!res))
670 g_free (buf->empty_seg);
671 buf->empty_seg = NULL;
672 gst_caps_replace (&buf->spec.caps, NULL);
673 gst_audio_info_init (&buf->spec.info);
674 GST_DEBUG_OBJECT (buf, "released device");
677 GST_OBJECT_UNLOCK (buf);
685 GST_DEBUG_OBJECT (buf, "device was released");
690 buf->acquired = TRUE;
691 GST_DEBUG_OBJECT (buf, "failed to release device");
697 * gst_audio_ring_buffer_is_acquired:
698 * @buf: the #GstAudioRingBuffer to check
700 * Check if the ringbuffer is acquired and ready to use.
702 * Returns: TRUE if the ringbuffer is acquired, FALSE on error.
707 gst_audio_ring_buffer_is_acquired (GstAudioRingBuffer * buf)
711 g_return_val_if_fail (GST_IS_AUDIO_RING_BUFFER (buf), FALSE);
713 GST_OBJECT_LOCK (buf);
715 GST_OBJECT_UNLOCK (buf);
721 * gst_audio_ring_buffer_activate:
722 * @buf: the #GstAudioRingBuffer to activate
723 * @active: the new mode
725 * Activate @buf to start or stop pulling data.
729 * Returns: TRUE if the device could be activated in the requested mode,
733 gst_audio_ring_buffer_activate (GstAudioRingBuffer * buf, gboolean active)
735 gboolean res = FALSE;
736 GstAudioRingBufferClass *rclass;
738 g_return_val_if_fail (GST_IS_AUDIO_RING_BUFFER (buf), FALSE);
740 GST_DEBUG_OBJECT (buf, "activate device");
742 GST_OBJECT_LOCK (buf);
743 if (G_UNLIKELY (active && !buf->acquired))
746 if (G_UNLIKELY (buf->active == active))
749 rclass = GST_AUDIO_RING_BUFFER_GET_CLASS (buf);
750 /* if there is no activate function we assume it was started/released
751 * in the acquire method */
752 if (G_LIKELY (rclass->activate))
753 res = rclass->activate (buf, active);
757 if (G_UNLIKELY (!res))
758 goto activate_failed;
760 buf->active = active;
763 GST_OBJECT_UNLOCK (buf);
770 GST_DEBUG_OBJECT (buf, "device not acquired");
771 g_critical ("Device for %p not acquired", buf);
778 GST_DEBUG_OBJECT (buf, "device was active in mode %d", active);
783 GST_DEBUG_OBJECT (buf, "failed to activate device");
789 * gst_audio_ring_buffer_is_active:
790 * @buf: the #GstAudioRingBuffer
792 * Check if @buf is activated.
796 * Returns: TRUE if the device is active.
799 gst_audio_ring_buffer_is_active (GstAudioRingBuffer * buf)
803 g_return_val_if_fail (GST_IS_AUDIO_RING_BUFFER (buf), FALSE);
805 GST_OBJECT_LOCK (buf);
807 GST_OBJECT_UNLOCK (buf);
814 * gst_audio_ring_buffer_set_flushing:
815 * @buf: the #GstAudioRingBuffer to flush
816 * @flushing: the new mode
818 * Set the ringbuffer to flushing mode or normal mode.
823 gst_audio_ring_buffer_set_flushing (GstAudioRingBuffer * buf, gboolean flushing)
825 g_return_if_fail (GST_IS_AUDIO_RING_BUFFER (buf));
827 GST_OBJECT_LOCK (buf);
828 buf->flushing = flushing;
831 gst_audio_ring_buffer_pause_unlocked (buf);
833 gst_audio_ring_buffer_clear_all (buf);
835 GST_OBJECT_UNLOCK (buf);
839 * gst_audio_ring_buffer_is_flushing:
840 * @buf: the #GstAudioRingBuffer
842 * Check if @buf is flushing.
846 * Returns: TRUE if the device is flushing.
849 gst_audio_ring_buffer_is_flushing (GstAudioRingBuffer * buf)
853 g_return_val_if_fail (GST_IS_AUDIO_RING_BUFFER (buf), TRUE);
855 GST_OBJECT_LOCK (buf);
857 GST_OBJECT_UNLOCK (buf);
863 * gst_audio_ring_buffer_start:
864 * @buf: the #GstAudioRingBuffer to start
866 * Start processing samples from the ringbuffer.
868 * Returns: TRUE if the device could be started, FALSE on error.
873 gst_audio_ring_buffer_start (GstAudioRingBuffer * buf)
875 gboolean res = FALSE;
876 GstAudioRingBufferClass *rclass;
877 gboolean resume = FALSE;
879 g_return_val_if_fail (GST_IS_AUDIO_RING_BUFFER (buf), FALSE);
881 GST_DEBUG_OBJECT (buf, "starting ringbuffer");
883 GST_OBJECT_LOCK (buf);
884 if (G_UNLIKELY (buf->flushing))
887 if (G_UNLIKELY (!buf->acquired))
890 if (G_UNLIKELY (g_atomic_int_get (&buf->may_start) == FALSE))
893 /* if stopped, set to started */
894 res = g_atomic_int_compare_and_exchange (&buf->state,
895 GST_AUDIO_RING_BUFFER_STATE_STOPPED, GST_AUDIO_RING_BUFFER_STATE_STARTED);
898 GST_DEBUG_OBJECT (buf, "was not stopped, try paused");
899 /* was not stopped, try from paused */
900 res = g_atomic_int_compare_and_exchange (&buf->state,
901 GST_AUDIO_RING_BUFFER_STATE_PAUSED,
902 GST_AUDIO_RING_BUFFER_STATE_STARTED);
904 /* was not paused either, must be started then */
906 GST_DEBUG_OBJECT (buf, "was not paused, must have been started");
910 GST_DEBUG_OBJECT (buf, "resuming");
913 rclass = GST_AUDIO_RING_BUFFER_GET_CLASS (buf);
915 if (G_LIKELY (rclass->resume))
916 res = rclass->resume (buf);
918 if (G_LIKELY (rclass->start))
919 res = rclass->start (buf);
922 if (G_UNLIKELY (!res)) {
923 buf->state = GST_AUDIO_RING_BUFFER_STATE_PAUSED;
924 GST_DEBUG_OBJECT (buf, "failed to start");
926 GST_DEBUG_OBJECT (buf, "started");
930 GST_OBJECT_UNLOCK (buf);
936 GST_DEBUG_OBJECT (buf, "we are flushing");
937 GST_OBJECT_UNLOCK (buf);
942 GST_DEBUG_OBJECT (buf, "we are not acquired");
943 GST_OBJECT_UNLOCK (buf);
948 GST_DEBUG_OBJECT (buf, "we may not start");
949 GST_OBJECT_UNLOCK (buf);
955 gst_audio_ring_buffer_pause_unlocked (GstAudioRingBuffer * buf)
957 gboolean res = FALSE;
958 GstAudioRingBufferClass *rclass;
960 GST_DEBUG_OBJECT (buf, "pausing ringbuffer");
962 /* if started, set to paused */
963 res = g_atomic_int_compare_and_exchange (&buf->state,
964 GST_AUDIO_RING_BUFFER_STATE_STARTED, GST_AUDIO_RING_BUFFER_STATE_PAUSED);
969 /* signal any waiters */
970 GST_DEBUG_OBJECT (buf, "signal waiter");
971 GST_AUDIO_RING_BUFFER_SIGNAL (buf);
973 rclass = GST_AUDIO_RING_BUFFER_GET_CLASS (buf);
974 if (G_LIKELY (rclass->pause))
975 res = rclass->pause (buf);
977 if (G_UNLIKELY (!res)) {
978 buf->state = GST_AUDIO_RING_BUFFER_STATE_STARTED;
979 GST_DEBUG_OBJECT (buf, "failed to pause");
981 GST_DEBUG_OBJECT (buf, "paused");
988 /* was not started */
989 GST_DEBUG_OBJECT (buf, "was not started");
995 * gst_audio_ring_buffer_pause:
996 * @buf: the #GstAudioRingBuffer to pause
998 * Pause processing samples from the ringbuffer.
1000 * Returns: TRUE if the device could be paused, FALSE on error.
1005 gst_audio_ring_buffer_pause (GstAudioRingBuffer * buf)
1007 gboolean res = FALSE;
1009 g_return_val_if_fail (GST_IS_AUDIO_RING_BUFFER (buf), FALSE);
1011 GST_OBJECT_LOCK (buf);
1012 if (G_UNLIKELY (buf->flushing))
1015 if (G_UNLIKELY (!buf->acquired))
1018 res = gst_audio_ring_buffer_pause_unlocked (buf);
1019 GST_OBJECT_UNLOCK (buf);
1026 GST_DEBUG_OBJECT (buf, "we are flushing");
1027 GST_OBJECT_UNLOCK (buf);
1032 GST_DEBUG_OBJECT (buf, "not acquired");
1033 GST_OBJECT_UNLOCK (buf);
1039 * gst_audio_ring_buffer_stop:
1040 * @buf: the #GstAudioRingBuffer to stop
1042 * Stop processing samples from the ringbuffer.
1044 * Returns: TRUE if the device could be stopped, FALSE on error.
1049 gst_audio_ring_buffer_stop (GstAudioRingBuffer * buf)
1051 gboolean res = FALSE;
1052 GstAudioRingBufferClass *rclass;
1054 g_return_val_if_fail (GST_IS_AUDIO_RING_BUFFER (buf), FALSE);
1056 GST_DEBUG_OBJECT (buf, "stopping");
1058 GST_OBJECT_LOCK (buf);
1060 /* if started, set to stopped */
1061 res = g_atomic_int_compare_and_exchange (&buf->state,
1062 GST_AUDIO_RING_BUFFER_STATE_STARTED, GST_AUDIO_RING_BUFFER_STATE_STOPPED);
1065 GST_DEBUG_OBJECT (buf, "was not started, try paused");
1066 /* was not started, try from paused */
1067 res = g_atomic_int_compare_and_exchange (&buf->state,
1068 GST_AUDIO_RING_BUFFER_STATE_PAUSED,
1069 GST_AUDIO_RING_BUFFER_STATE_STOPPED);
1071 /* was not paused either, must have been stopped then */
1073 GST_DEBUG_OBJECT (buf, "was not paused, must have been stopped");
1078 /* signal any waiters */
1079 GST_DEBUG_OBJECT (buf, "signal waiter");
1080 GST_AUDIO_RING_BUFFER_SIGNAL (buf);
1082 rclass = GST_AUDIO_RING_BUFFER_GET_CLASS (buf);
1083 if (G_LIKELY (rclass->stop))
1084 res = rclass->stop (buf);
1086 if (G_UNLIKELY (!res)) {
1087 buf->state = GST_AUDIO_RING_BUFFER_STATE_STARTED;
1088 GST_DEBUG_OBJECT (buf, "failed to stop");
1090 GST_DEBUG_OBJECT (buf, "stopped");
1093 GST_OBJECT_UNLOCK (buf);
1099 * gst_audio_ring_buffer_delay:
1100 * @buf: the #GstAudioRingBuffer to query
1102 * Get the number of samples queued in the audio device. This is
1103 * usually less than the segment size but can be bigger when the
1104 * implementation uses another internal buffer between the audio
1107 * For playback ringbuffers this is the amount of samples transfered from the
1108 * ringbuffer to the device but still not played.
1110 * For capture ringbuffers this is the amount of samples in the device that are
1111 * not yet transfered to the ringbuffer.
1113 * Returns: The number of samples queued in the audio device.
1118 gst_audio_ring_buffer_delay (GstAudioRingBuffer * buf)
1120 GstAudioRingBufferClass *rclass;
1123 g_return_val_if_fail (GST_IS_AUDIO_RING_BUFFER (buf), 0);
1125 /* buffer must be acquired */
1126 if (G_UNLIKELY (!gst_audio_ring_buffer_is_acquired (buf)))
1129 rclass = GST_AUDIO_RING_BUFFER_GET_CLASS (buf);
1130 if (G_LIKELY (rclass->delay))
1131 res = rclass->delay (buf);
1139 GST_DEBUG_OBJECT (buf, "not acquired");
1145 * gst_audio_ring_buffer_samples_done:
1146 * @buf: the #GstAudioRingBuffer to query
1148 * Get the number of samples that were processed by the ringbuffer
1149 * since it was last started. This does not include the number of samples not
1150 * yet processed (see gst_audio_ring_buffer_delay()).
1152 * Returns: The number of samples processed by the ringbuffer.
1157 gst_audio_ring_buffer_samples_done (GstAudioRingBuffer * buf)
1162 g_return_val_if_fail (GST_IS_AUDIO_RING_BUFFER (buf), 0);
1164 /* get the amount of segments we processed */
1165 segdone = g_atomic_int_get (&buf->segdone);
1167 /* convert to samples */
1168 samples = ((guint64) segdone) * buf->samples_per_seg;
1174 * gst_audio_ring_buffer_set_sample:
1175 * @buf: the #GstAudioRingBuffer to use
1176 * @sample: the sample number to set
1178 * Make sure that the next sample written to the device is
1179 * accounted for as being the @sample sample written to the
1180 * device. This value will be used in reporting the current
1181 * sample position of the ringbuffer.
1183 * This function will also clear the buffer with silence.
1188 gst_audio_ring_buffer_set_sample (GstAudioRingBuffer * buf, guint64 sample)
1190 g_return_if_fail (GST_IS_AUDIO_RING_BUFFER (buf));
1195 if (G_UNLIKELY (buf->samples_per_seg == 0))
1198 /* FIXME, we assume the ringbuffer can restart at a random
1199 * position, round down to the beginning and keep track of
1200 * offset when calculating the processed samples. */
1201 buf->segbase = buf->segdone - sample / buf->samples_per_seg;
1203 gst_audio_ring_buffer_clear_all (buf);
1205 GST_DEBUG_OBJECT (buf, "set sample to %" G_GUINT64_FORMAT ", segbase %d",
1206 sample, buf->segbase);
1210 default_clear_all (GstAudioRingBuffer * buf)
1214 /* not fatal, we just are not negotiated yet */
1215 if (G_UNLIKELY (buf->spec.segtotal <= 0))
1218 GST_DEBUG_OBJECT (buf, "clear all segments");
1220 for (i = 0; i < buf->spec.segtotal; i++) {
1221 gst_audio_ring_buffer_clear (buf, i);
1226 * gst_audio_ring_buffer_clear_all:
1227 * @buf: the #GstAudioRingBuffer to clear
1229 * Fill the ringbuffer with silence.
1234 gst_audio_ring_buffer_clear_all (GstAudioRingBuffer * buf)
1236 GstAudioRingBufferClass *rclass;
1238 g_return_if_fail (GST_IS_AUDIO_RING_BUFFER (buf));
1240 rclass = GST_AUDIO_RING_BUFFER_GET_CLASS (buf);
1242 if (G_LIKELY (rclass->clear_all))
1243 rclass->clear_all (buf);
1248 wait_segment (GstAudioRingBuffer * buf)
1251 gboolean wait = TRUE;
1253 /* buffer must be started now or we deadlock since nobody is reading */
1254 if (G_UNLIKELY (g_atomic_int_get (&buf->state) !=
1255 GST_AUDIO_RING_BUFFER_STATE_STARTED)) {
1256 /* see if we are allowed to start it */
1257 if (G_UNLIKELY (g_atomic_int_get (&buf->may_start) == FALSE))
1260 GST_DEBUG_OBJECT (buf, "start!");
1261 segments = g_atomic_int_get (&buf->segdone);
1262 gst_audio_ring_buffer_start (buf);
1264 /* After starting, the writer may have wrote segments already and then we
1265 * don't need to wait anymore */
1266 if (G_LIKELY (g_atomic_int_get (&buf->segdone) != segments))
1270 /* take lock first, then update our waiting flag */
1271 GST_OBJECT_LOCK (buf);
1272 if (G_UNLIKELY (buf->flushing))
1275 if (G_UNLIKELY (g_atomic_int_get (&buf->state) !=
1276 GST_AUDIO_RING_BUFFER_STATE_STARTED))
1279 if (G_LIKELY (wait)) {
1280 if (g_atomic_int_compare_and_exchange (&buf->waiting, 0, 1)) {
1281 GST_DEBUG_OBJECT (buf, "waiting..");
1282 GST_AUDIO_RING_BUFFER_WAIT (buf);
1284 if (G_UNLIKELY (buf->flushing))
1287 if (G_UNLIKELY (g_atomic_int_get (&buf->state) !=
1288 GST_AUDIO_RING_BUFFER_STATE_STARTED))
1292 GST_OBJECT_UNLOCK (buf);
1299 g_atomic_int_compare_and_exchange (&buf->waiting, 1, 0);
1300 GST_DEBUG_OBJECT (buf, "stopped processing");
1301 GST_OBJECT_UNLOCK (buf);
1306 g_atomic_int_compare_and_exchange (&buf->waiting, 1, 0);
1307 GST_DEBUG_OBJECT (buf, "flushing");
1308 GST_OBJECT_UNLOCK (buf);
1313 GST_DEBUG_OBJECT (buf, "not allowed to start");
1320 #define REORDER_SAMPLE(d, s, l) \
1323 for (i = 0; i < channels; i++) { \
1324 memcpy (d + reorder_map[i] * bps, s + i * bps, bps); \
1328 #define REORDER_SAMPLES(d, s, len) \
1330 gint i, len_ = len / bpf; \
1331 guint8 *d_ = d, *s_ = s; \
1332 for (i = 0; i < len_; i++) { \
1333 REORDER_SAMPLE(d_, s_, bpf); \
1339 #define FWD_SAMPLES(s,se,d,de,F) \
1341 /* no rate conversion */ \
1342 guint towrite = MIN (se + bpf - s, de - d); \
1345 F (d, s, towrite); \
1346 in_samples -= towrite / bpf; \
1347 out_samples -= towrite / bpf; \
1349 GST_DEBUG ("copy %u bytes", towrite); \
1352 /* in_samples >= out_samples, rate > 1.0 */
1353 #define FWD_UP_SAMPLES(s,se,d,de,F) \
1355 guint8 *sb = s, *db = d; \
1356 while (s <= se && d < de) { \
1361 if ((*accum << 1) >= inr) { \
1366 in_samples -= (s - sb)/bpf; \
1367 out_samples -= (d - db)/bpf; \
1368 GST_DEBUG ("fwd_up end %d/%d",*accum,*toprocess); \
1371 /* out_samples > in_samples, for rates smaller than 1.0 */
1372 #define FWD_DOWN_SAMPLES(s,se,d,de,F) \
1374 guint8 *sb = s, *db = d; \
1375 while (s <= se && d < de) { \
1380 if ((*accum << 1) >= outr) { \
1385 in_samples -= (s - sb)/bpf; \
1386 out_samples -= (d - db)/bpf; \
1387 GST_DEBUG ("fwd_down end %d/%d",*accum,*toprocess); \
1390 #define REV_UP_SAMPLES(s,se,d,de,F) \
1392 guint8 *sb = se, *db = d; \
1393 while (s <= se && d < de) { \
1398 while (d < de && (*accum << 1) >= inr) { \
1403 in_samples -= (sb - se)/bpf; \
1404 out_samples -= (d - db)/bpf; \
1405 GST_DEBUG ("rev_up end %d/%d",*accum,*toprocess); \
1408 #define REV_DOWN_SAMPLES(s,se,d,de,F) \
1410 guint8 *sb = se, *db = d; \
1411 while (s <= se && d < de) { \
1416 while (s <= se && (*accum << 1) >= outr) { \
1421 in_samples -= (sb - se)/bpf; \
1422 out_samples -= (d - db)/bpf; \
1423 GST_DEBUG ("rev_down end %d/%d",*accum,*toprocess); \
1427 default_commit (GstAudioRingBuffer * buf, guint64 * sample,
1428 guint8 * data, gint in_samples, gint out_samples, gint * accum)
1431 gint segsize, segtotal, channels, bps, bpf, sps;
1432 guint8 *dest, *data_end;
1433 gint writeseg, sampleoff;
1437 gboolean need_reorder;
1439 g_return_val_if_fail (buf->memory != NULL, -1);
1440 g_return_val_if_fail (data != NULL, -1);
1442 need_reorder = buf->need_reorder;
1444 channels = buf->spec.info.channels;
1446 segsize = buf->spec.segsize;
1447 segtotal = buf->spec.segtotal;
1448 bpf = buf->spec.info.bpf;
1449 bps = bpf / channels;
1450 sps = buf->samples_per_seg;
1452 reverse = out_samples < 0;
1453 out_samples = ABS (out_samples);
1455 if (in_samples >= out_samples)
1456 toprocess = &in_samples;
1458 toprocess = &out_samples;
1460 inr = in_samples - 1;
1461 outr = out_samples - 1;
1463 /* data_end points to the last sample we have to write, not past it. This is
1464 * needed to properly handle reverse playback: it points to the last sample. */
1465 data_end = data + (bpf * inr);
1467 /* figure out the segment and the offset inside the segment where
1468 * the first sample should be written. */
1469 writeseg = *sample / sps;
1470 sampleoff = (*sample % sps) * bpf;
1472 /* write out all samples */
1473 while (*toprocess > 0) {
1482 /* get the currently processed segment */
1483 segdone = g_atomic_int_get (&buf->segdone) - buf->segbase;
1485 /* see how far away it is from the write segment */
1486 diff = writeseg - segdone;
1489 ("pointer at %d, write to %d-%d, diff %d, segtotal %d, segsize %d, base %d",
1490 segdone, writeseg, sampleoff, diff, segtotal, segsize, buf->segbase);
1492 /* segment too far ahead, writer too slow, we need to drop, hopefully UNLIKELY */
1493 if (G_UNLIKELY (diff < 0)) {
1494 /* we need to drop one segment at a time, pretend we wrote a
1500 /* write segment is within writable range, we can break the loop and
1501 * start writing the data. */
1502 if (diff < segtotal) {
1507 /* else we need to wait for the segment to become writable. */
1508 if (!wait_segment (buf))
1512 /* we can write now */
1513 ws = writeseg % segtotal;
1514 avail = MIN (segsize - sampleoff, bpf * out_samples);
1516 d = dest + (ws * segsize) + sampleoff;
1518 *sample += avail / bpf;
1520 GST_DEBUG_OBJECT (buf, "write @%p seg %d, sps %d, off %d, avail %d",
1521 dest + ws * segsize, ws, sps, sampleoff, avail);
1524 gint *reorder_map = buf->channel_reorder_map;
1526 if (G_LIKELY (inr == outr && !reverse)) {
1527 /* no rate conversion, simply copy samples */
1528 FWD_SAMPLES (data, data_end, d, d_end, REORDER_SAMPLES);
1529 } else if (!reverse) {
1531 /* forward speed up */
1532 FWD_UP_SAMPLES (data, data_end, d, d_end, REORDER_SAMPLE);
1534 /* forward slow down */
1535 FWD_DOWN_SAMPLES (data, data_end, d, d_end, REORDER_SAMPLE);
1538 /* reverse speed up */
1539 REV_UP_SAMPLES (data, data_end, d, d_end, REORDER_SAMPLE);
1541 /* reverse slow down */
1542 REV_DOWN_SAMPLES (data, data_end, d, d_end, REORDER_SAMPLE);
1545 if (G_LIKELY (inr == outr && !reverse)) {
1546 /* no rate conversion, simply copy samples */
1547 FWD_SAMPLES (data, data_end, d, d_end, memcpy);
1548 } else if (!reverse) {
1550 /* forward speed up */
1551 FWD_UP_SAMPLES (data, data_end, d, d_end, memcpy);
1553 /* forward slow down */
1554 FWD_DOWN_SAMPLES (data, data_end, d, d_end, memcpy);
1557 /* reverse speed up */
1558 REV_UP_SAMPLES (data, data_end, d, d_end, memcpy);
1560 /* reverse slow down */
1561 REV_DOWN_SAMPLES (data, data_end, d, d_end, memcpy);
1565 /* for the next iteration we write to the next segment at the beginning. */
1569 /* we consumed all samples here */
1570 data = data_end + bpf;
1573 return inr - ((data_end - data) / bpf);
1578 GST_DEBUG_OBJECT (buf, "stopped processing");
1584 * gst_audio_ring_buffer_commit:
1585 * @buf: the #GstAudioRingBuffer to commit
1586 * @sample: the sample position of the data
1587 * @data: the data to commit
1588 * @in_samples: the number of samples in the data to commit
1589 * @out_samples: the number of samples to write to the ringbuffer
1590 * @accum: accumulator for rate conversion.
1592 * Commit @in_samples samples pointed to by @data to the ringbuffer @buf.
1594 * @in_samples and @out_samples define the rate conversion to perform on the
1595 * samples in @data. For negative rates, @out_samples must be negative and
1596 * @in_samples positive.
1598 * When @out_samples is positive, the first sample will be written at position @sample
1599 * in the ringbuffer. When @out_samples is negative, the last sample will be written to
1600 * @sample in reverse order.
1602 * @out_samples does not need to be a multiple of the segment size of the ringbuffer
1603 * although it is recommended for optimal performance.
1605 * @accum will hold a temporary accumulator used in rate conversion and should be
1606 * set to 0 when this function is first called. In case the commit operation is
1607 * interrupted, one can resume the processing by passing the previously returned
1608 * @accum value back to this function.
1612 * Returns: The number of samples written to the ringbuffer or -1 on error. The
1613 * number of samples written can be less than @out_samples when @buf was interrupted
1614 * with a flush or stop.
1617 gst_audio_ring_buffer_commit (GstAudioRingBuffer * buf, guint64 * sample,
1618 guint8 * data, gint in_samples, gint out_samples, gint * accum)
1620 GstAudioRingBufferClass *rclass;
1623 g_return_val_if_fail (GST_IS_AUDIO_RING_BUFFER (buf), -1);
1625 if (G_UNLIKELY (in_samples == 0 || out_samples == 0))
1628 rclass = GST_AUDIO_RING_BUFFER_GET_CLASS (buf);
1630 if (G_LIKELY (rclass->commit))
1631 res = rclass->commit (buf, sample, data, in_samples, out_samples, accum);
1637 * gst_audio_ring_buffer_read:
1638 * @buf: the #GstAudioRingBuffer to read from
1639 * @sample: the sample position of the data
1640 * @data: where the data should be read
1641 * @len: the number of samples in data to read
1642 * @timestamp: where the timestamp is returned
1644 * Read @len samples from the ringbuffer into the memory pointed
1646 * The first sample should be read from position @sample in
1649 * @len should not be a multiple of the segment size of the ringbuffer
1650 * although it is recommended.
1652 * @timestamp will return the timestamp associated with the data returned.
1654 * Returns: The number of samples read from the ringbuffer or -1 on
1660 gst_audio_ring_buffer_read (GstAudioRingBuffer * buf, guint64 sample,
1661 guint8 * data, guint len, GstClockTime * timestamp)
1664 gint segsize, segtotal, channels, bps, bpf, sps, readseg = 0;
1667 gboolean need_reorder;
1669 g_return_val_if_fail (GST_IS_AUDIO_RING_BUFFER (buf), -1);
1670 g_return_val_if_fail (buf->memory != NULL, -1);
1671 g_return_val_if_fail (data != NULL, -1);
1673 need_reorder = buf->need_reorder;
1675 segsize = buf->spec.segsize;
1676 segtotal = buf->spec.segtotal;
1677 channels = buf->spec.info.channels;
1678 bpf = buf->spec.info.bpf;
1679 bps = bpf / channels;
1680 sps = buf->samples_per_seg;
1683 /* read enough samples */
1684 while (to_read > 0) {
1688 /* figure out the segment and the offset inside the segment where
1689 * the sample should be read from. */
1690 readseg = sample / sps;
1691 sampleoff = (sample % sps);
1696 /* get the currently processed segment */
1697 segdone = g_atomic_int_get (&buf->segdone) - buf->segbase;
1699 /* see how far away it is from the read segment, normally segdone (where
1700 * the hardware is writing) is bigger than readseg (where software is
1702 diff = segdone - readseg;
1705 ("pointer at %d, sample %" G_GUINT64_FORMAT
1706 ", read from %d-%d, to_read %d, diff %d, segtotal %d, segsize %d",
1707 segdone, sample, readseg, sampleoff, to_read, diff, segtotal,
1710 /* segment too far ahead, reader too slow */
1711 if (G_UNLIKELY (diff >= segtotal)) {
1712 /* pretend we read an empty segment. */
1713 sampleslen = MIN (sps, to_read);
1714 memcpy (data, buf->empty_seg, sampleslen * bpf);
1718 /* read segment is within readable range, we can break the loop and
1719 * start reading the data. */
1723 /* else we need to wait for the segment to become readable. */
1724 if (!wait_segment (buf))
1728 /* we can read now */
1729 readseg = readseg % segtotal;
1730 sampleslen = MIN (sps - sampleoff, to_read);
1732 GST_DEBUG_OBJECT (buf, "read @%p seg %d, off %d, sampleslen %d",
1733 dest + readseg * segsize, readseg, sampleoff, sampleslen);
1736 guint8 *ptr = dest + (readseg * segsize) + (sampleoff * bpf);
1738 gint *reorder_map = buf->channel_reorder_map;
1740 /* Reorder from device order to GStreamer order */
1741 for (i = 0; i < sampleslen; i++) {
1742 for (j = 0; j < channels; j++) {
1743 memcpy (data + reorder_map[j] * bps, ptr + j * bps, bps);
1748 memcpy (data, dest + (readseg * segsize) + (sampleoff * bpf),
1749 (sampleslen * bpf));
1753 to_read -= sampleslen;
1754 sample += sampleslen;
1755 data += sampleslen * bpf;
1758 if (buf->timestamps && timestamp) {
1759 *timestamp = buf->timestamps[readseg % segtotal];
1760 GST_INFO_OBJECT (buf, "Retrieved timestamp %" GST_TIME_FORMAT
1761 " @ %d", GST_TIME_ARGS (*timestamp), readseg % segtotal);
1764 return len - to_read;
1769 GST_DEBUG_OBJECT (buf, "stopped processing");
1770 return len - to_read;
1775 * gst_audio_ring_buffer_prepare_read:
1776 * @buf: the #GstAudioRingBuffer to read from
1777 * @segment: the segment to read
1778 * @readptr: the pointer to the memory where samples can be read
1779 * @len: the number of bytes to read
1781 * Returns a pointer to memory where the data from segment @segment
1782 * can be found. This function is mostly used by subclasses.
1784 * Returns: FALSE if the buffer is not started.
1789 gst_audio_ring_buffer_prepare_read (GstAudioRingBuffer * buf, gint * segment,
1790 guint8 ** readptr, gint * len)
1795 g_return_val_if_fail (GST_IS_AUDIO_RING_BUFFER (buf), FALSE);
1797 if (buf->callback == NULL) {
1798 /* push mode, fail when nothing is started */
1799 if (g_atomic_int_get (&buf->state) != GST_AUDIO_RING_BUFFER_STATE_STARTED)
1803 g_return_val_if_fail (buf->memory != NULL, FALSE);
1804 g_return_val_if_fail (segment != NULL, FALSE);
1805 g_return_val_if_fail (readptr != NULL, FALSE);
1806 g_return_val_if_fail (len != NULL, FALSE);
1810 /* get the position of the pointer */
1811 segdone = g_atomic_int_get (&buf->segdone);
1813 *segment = segdone % buf->spec.segtotal;
1814 *len = buf->spec.segsize;
1815 *readptr = data + *segment * *len;
1817 GST_LOG ("prepare read from segment %d (real %d) @%p",
1818 *segment, segdone, *readptr);
1820 /* callback to fill the memory with data, for pull based
1823 buf->callback (buf, *readptr, *len, buf->cb_data);
1829 * gst_audio_ring_buffer_advance:
1830 * @buf: the #GstAudioRingBuffer to advance
1831 * @advance: the number of segments written
1833 * Subclasses should call this function to notify the fact that
1834 * @advance segments are now processed by the device.
1839 gst_audio_ring_buffer_advance (GstAudioRingBuffer * buf, guint advance)
1841 g_return_if_fail (GST_IS_AUDIO_RING_BUFFER (buf));
1843 /* update counter */
1844 g_atomic_int_add (&buf->segdone, advance);
1846 /* the lock is already taken when the waiting flag is set,
1847 * we grab the lock as well to make sure the waiter is actually
1848 * waiting for the signal */
1849 if (g_atomic_int_compare_and_exchange (&buf->waiting, 1, 0)) {
1850 GST_OBJECT_LOCK (buf);
1851 GST_DEBUG_OBJECT (buf, "signal waiter");
1852 GST_AUDIO_RING_BUFFER_SIGNAL (buf);
1853 GST_OBJECT_UNLOCK (buf);
1858 * gst_audio_ring_buffer_clear:
1859 * @buf: the #GstAudioRingBuffer to clear
1860 * @segment: the segment to clear
1862 * Clear the given segment of the buffer with silence samples.
1863 * This function is used by subclasses.
1868 gst_audio_ring_buffer_clear (GstAudioRingBuffer * buf, gint segment)
1872 g_return_if_fail (GST_IS_AUDIO_RING_BUFFER (buf));
1874 /* no data means it's already cleared */
1875 if (G_UNLIKELY (buf->memory == NULL))
1878 /* no empty_seg means it's not opened */
1879 if (G_UNLIKELY (buf->empty_seg == NULL))
1882 segment %= buf->spec.segtotal;
1885 data += segment * buf->spec.segsize;
1887 GST_LOG ("clear segment %d @%p", segment, data);
1889 memcpy (data, buf->empty_seg, buf->spec.segsize);
1893 * gst_audio_ring_buffer_may_start:
1894 * @buf: the #GstAudioRingBuffer
1895 * @allowed: the new value
1897 * Tell the ringbuffer that it is allowed to start playback when
1898 * the ringbuffer is filled with samples.
1903 gst_audio_ring_buffer_may_start (GstAudioRingBuffer * buf, gboolean allowed)
1905 g_return_if_fail (GST_IS_AUDIO_RING_BUFFER (buf));
1907 GST_LOG_OBJECT (buf, "may start: %d", allowed);
1908 g_atomic_int_set (&buf->may_start, allowed);
1912 * gst_audio_ring_buffer_set_channel_positions:
1913 * @buf: the #GstAudioRingBuffer
1914 * @position: the device channel positions
1916 * Tell the ringbuffer about the device's channel positions. This must
1917 * be called in when the ringbuffer is acquired.
1920 gst_audio_ring_buffer_set_channel_positions (GstAudioRingBuffer * buf,
1921 const GstAudioChannelPosition * position)
1923 const GstAudioChannelPosition *to;
1927 g_return_if_fail (GST_IS_AUDIO_RING_BUFFER (buf));
1928 g_return_if_fail (buf->acquired);
1930 channels = buf->spec.info.channels;
1931 to = buf->spec.info.position;
1933 buf->need_reorder = FALSE;
1934 if (memcmp (position, to, channels * sizeof (to[0])) == 0)
1937 if (!gst_audio_get_channel_reorder_map (channels, position, to,
1938 buf->channel_reorder_map))
1939 g_return_if_reached ();
1941 for (i = 0; i < channels; i++) {
1942 if (buf->channel_reorder_map[i] != i) {
1943 buf->need_reorder = TRUE;
1950 * gst_ring_buffer_set_timestamp:
1951 * @buf: the #GstRingBuffer
1952 * @readseg: the current data segment
1953 * @timestamp: The new timestamp of the buffer.
1955 * Set a new timestamp on the buffer.
1962 gst_audio_ring_buffer_set_timestamp (GstAudioRingBuffer * buf, gint readseg,
1963 GstClockTime timestamp)
1965 g_return_if_fail (GST_IS_AUDIO_RING_BUFFER (buf));
1967 GST_INFO_OBJECT (buf, "Storing timestamp %" GST_TIME_FORMAT
1968 " @ %d", GST_TIME_ARGS (timestamp), readseg);
1969 if (buf->timestamps) {
1970 buf->timestamps[readseg] = timestamp;
1972 GST_ERROR_OBJECT (buf, "Could not store timestamp, no timestamps buffer");