2 * Copyright (C) 2005 Wim Taymans <wim@fluendo.com>
3 * Copyright (C) 2006 Tim-Philipp Müller <tim centricular net>
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
24 * SECTION:element-alsasink
28 * This element renders audio samples using the ALSA audio API.
30 * ## Example pipelines
32 * gst-launch-1.0 -v uridecodebin uri=file:///path/to/audio.ogg ! audioconvert ! audioresample ! autoaudiosink
35 * Play an Ogg/Vorbis file and output audio via ALSA.
42 #include <sys/ioctl.h>
48 #include <alsa/asoundlib.h>
50 #include "gstalsaelements.h"
52 #include "gstalsasink.h"
54 #include <gst/audio/gstaudioiec61937.h>
55 #include <glib/gi18n-lib.h>
58 #define ESTRPIPE EPIPE
61 #define DEFAULT_DEVICE "default"
62 #define DEFAULT_DEVICE_NAME ""
63 #define DEFAULT_CARD_NAME ""
64 #define SPDIF_PERIOD_SIZE 1536
65 #define SPDIF_BUFFER_SIZE 15360
76 #define gst_alsasink_parent_class parent_class
77 G_DEFINE_TYPE (GstAlsaSink, gst_alsasink, GST_TYPE_AUDIO_SINK);
78 GST_ELEMENT_REGISTER_DEFINE_WITH_CODE (alsasink, "alsasink", GST_RANK_PRIMARY,
79 GST_TYPE_ALSA_SINK, alsa_element_init (plugin));
81 static void gst_alsasink_finalise (GObject * object);
82 static void gst_alsasink_set_property (GObject * object,
83 guint prop_id, const GValue * value, GParamSpec * pspec);
84 static void gst_alsasink_get_property (GObject * object,
85 guint prop_id, GValue * value, GParamSpec * pspec);
87 static GstCaps *gst_alsasink_getcaps (GstBaseSink * bsink, GstCaps * filter);
88 static gboolean gst_alsasink_query (GstBaseSink * bsink, GstQuery * query);
90 static gboolean gst_alsasink_open (GstAudioSink * asink);
91 static gboolean gst_alsasink_prepare (GstAudioSink * asink,
92 GstAudioRingBufferSpec * spec);
93 static gboolean gst_alsasink_unprepare (GstAudioSink * asink);
94 static gboolean gst_alsasink_close (GstAudioSink * asink);
95 static gint gst_alsasink_write (GstAudioSink * asink, gpointer data,
97 static guint gst_alsasink_delay (GstAudioSink * asink);
98 static void gst_alsasink_pause (GstAudioSink * asink);
99 static void gst_alsasink_resume (GstAudioSink * asink);
100 static void gst_alsasink_stop (GstAudioSink * asink);
101 static gboolean gst_alsasink_acceptcaps (GstAlsaSink * alsa, GstCaps * caps);
102 static GstBuffer *gst_alsasink_payload (GstAudioBaseSink * sink,
105 static gint output_ref; /* 0 */
106 static snd_output_t *output; /* NULL */
107 static GMutex output_mutex;
109 static GstStaticPadTemplate alsasink_sink_factory =
110 GST_STATIC_PAD_TEMPLATE ("sink",
113 GST_STATIC_CAPS ("audio/x-raw, "
114 "format = (string) " GST_AUDIO_FORMATS_ALL ", "
115 "layout = (string) interleaved, "
116 "rate = (int) [ 1, MAX ], " "channels = (int) [ 1, MAX ]; "
121 gst_alsasink_finalise (GObject * object)
123 GstAlsaSink *sink = GST_ALSA_SINK (object);
125 g_free (sink->device);
126 g_mutex_clear (&sink->alsa_lock);
127 g_mutex_clear (&sink->delay_lock);
129 g_mutex_lock (&output_mutex);
131 if (output_ref == 0) {
132 snd_output_close (output);
135 g_mutex_unlock (&output_mutex);
137 G_OBJECT_CLASS (parent_class)->finalize (object);
141 gst_alsasink_class_init (GstAlsaSinkClass * klass)
143 GObjectClass *gobject_class;
144 GstElementClass *gstelement_class;
145 GstBaseSinkClass *gstbasesink_class;
146 GstAudioBaseSinkClass *gstbaseaudiosink_class;
147 GstAudioSinkClass *gstaudiosink_class;
149 gobject_class = (GObjectClass *) klass;
150 gstelement_class = (GstElementClass *) klass;
151 gstbasesink_class = (GstBaseSinkClass *) klass;
152 gstbaseaudiosink_class = (GstAudioBaseSinkClass *) klass;
153 gstaudiosink_class = (GstAudioSinkClass *) klass;
155 parent_class = g_type_class_peek_parent (klass);
157 gobject_class->finalize = gst_alsasink_finalise;
158 gobject_class->get_property = gst_alsasink_get_property;
159 gobject_class->set_property = gst_alsasink_set_property;
161 gst_element_class_set_static_metadata (gstelement_class,
162 "Audio sink (ALSA)", "Sink/Audio",
163 "Output to a sound card via ALSA", "Wim Taymans <wim@fluendo.com>");
165 gst_element_class_add_static_pad_template (gstelement_class,
166 &alsasink_sink_factory);
168 gstbasesink_class->get_caps = GST_DEBUG_FUNCPTR (gst_alsasink_getcaps);
169 gstbasesink_class->query = GST_DEBUG_FUNCPTR (gst_alsasink_query);
171 gstbaseaudiosink_class->payload = GST_DEBUG_FUNCPTR (gst_alsasink_payload);
173 gstaudiosink_class->open = GST_DEBUG_FUNCPTR (gst_alsasink_open);
174 gstaudiosink_class->prepare = GST_DEBUG_FUNCPTR (gst_alsasink_prepare);
175 gstaudiosink_class->unprepare = GST_DEBUG_FUNCPTR (gst_alsasink_unprepare);
176 gstaudiosink_class->close = GST_DEBUG_FUNCPTR (gst_alsasink_close);
177 gstaudiosink_class->write = GST_DEBUG_FUNCPTR (gst_alsasink_write);
178 gstaudiosink_class->delay = GST_DEBUG_FUNCPTR (gst_alsasink_delay);
179 gstaudiosink_class->stop = GST_DEBUG_FUNCPTR (gst_alsasink_stop);
180 gstaudiosink_class->pause = GST_DEBUG_FUNCPTR (gst_alsasink_pause);
181 gstaudiosink_class->resume = GST_DEBUG_FUNCPTR (gst_alsasink_resume);
183 g_object_class_install_property (gobject_class, PROP_DEVICE,
184 g_param_spec_string ("device", "Device",
185 "ALSA device, as defined in an asound configuration file",
186 DEFAULT_DEVICE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
188 g_object_class_install_property (gobject_class, PROP_DEVICE_NAME,
189 g_param_spec_string ("device-name", "Device name",
190 "Human-readable name of the sound device", DEFAULT_DEVICE_NAME,
191 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
193 g_object_class_install_property (gobject_class, PROP_CARD_NAME,
194 g_param_spec_string ("card-name", "Card name",
195 "Human-readable name of the sound card", DEFAULT_CARD_NAME,
196 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS |
197 GST_PARAM_DOC_SHOW_DEFAULT));
201 gst_alsasink_set_property (GObject * object, guint prop_id,
202 const GValue * value, GParamSpec * pspec)
206 sink = GST_ALSA_SINK (object);
210 g_free (sink->device);
211 sink->device = g_value_dup_string (value);
212 /* setting NULL restores the default device */
213 if (sink->device == NULL) {
214 sink->device = g_strdup (DEFAULT_DEVICE);
218 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
224 gst_alsasink_get_property (GObject * object, guint prop_id,
225 GValue * value, GParamSpec * pspec)
229 sink = GST_ALSA_SINK (object);
233 g_value_set_string (value, sink->device);
235 case PROP_DEVICE_NAME:
236 g_value_take_string (value,
237 gst_alsa_find_device_name (GST_OBJECT_CAST (sink),
238 sink->device, sink->handle, SND_PCM_STREAM_PLAYBACK));
241 g_value_take_string (value,
242 gst_alsa_find_card_name (GST_OBJECT_CAST (sink),
243 sink->device, SND_PCM_STREAM_PLAYBACK));
246 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
252 gst_alsasink_init (GstAlsaSink * alsasink)
254 GST_DEBUG_OBJECT (alsasink, "initializing alsasink");
256 alsasink->device = g_strdup (DEFAULT_DEVICE);
257 alsasink->handle = NULL;
258 alsasink->cached_caps = NULL;
259 alsasink->is_paused = FALSE;
260 alsasink->after_paused = FALSE;
261 alsasink->hw_support_pause = FALSE;
262 alsasink->stop_streaming_threads = FALSE;
263 g_mutex_init (&alsasink->alsa_lock);
264 g_mutex_init (&alsasink->delay_lock);
266 g_mutex_lock (&output_mutex);
267 if (output_ref == 0) {
268 snd_output_stdio_attach (&output, stdout, 0);
271 g_mutex_unlock (&output_mutex);
274 #define CHECK(call, error) \
276 if ((err = call) < 0) { \
277 GST_WARNING_OBJECT (alsa, "Error %d (%s) calling " #call, err, snd_strerror (err)); \
283 gst_alsasink_getcaps (GstBaseSink * bsink, GstCaps * filter)
285 GstElementClass *element_class;
286 GstPadTemplate *pad_template;
287 GstAlsaSink *sink = GST_ALSA_SINK (bsink);
288 GstCaps *caps, *templ_caps;
290 GST_OBJECT_LOCK (sink);
291 if (sink->handle == NULL) {
292 GST_OBJECT_UNLOCK (sink);
293 GST_DEBUG_OBJECT (sink, "device not open, using template caps");
294 return NULL; /* base class will get template caps for us */
297 if (sink->cached_caps) {
299 caps = gst_caps_intersect_full (filter, sink->cached_caps,
300 GST_CAPS_INTERSECT_FIRST);
301 GST_OBJECT_UNLOCK (sink);
302 GST_LOG_OBJECT (sink, "Returning cached caps %" GST_PTR_FORMAT " with "
303 "filter %" GST_PTR_FORMAT " applied: %" GST_PTR_FORMAT,
304 sink->cached_caps, filter, caps);
307 caps = gst_caps_ref (sink->cached_caps);
308 GST_OBJECT_UNLOCK (sink);
309 GST_LOG_OBJECT (sink, "Returning cached caps %" GST_PTR_FORMAT, caps);
314 element_class = GST_ELEMENT_GET_CLASS (sink);
315 pad_template = gst_element_class_get_pad_template (element_class, "sink");
316 if (pad_template == NULL) {
317 GST_OBJECT_UNLOCK (sink);
318 g_assert_not_reached ();
322 templ_caps = gst_pad_template_get_caps (pad_template);
323 caps = gst_alsa_probe_supported_formats (GST_OBJECT (sink), sink->device,
324 sink->handle, templ_caps);
325 gst_caps_unref (templ_caps);
328 sink->cached_caps = gst_caps_ref (caps);
331 GST_OBJECT_UNLOCK (sink);
333 GST_INFO_OBJECT (sink, "returning caps %" GST_PTR_FORMAT, caps);
336 GstCaps *intersection;
339 gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);
340 gst_caps_unref (caps);
348 gst_alsasink_acceptcaps (GstAlsaSink * alsa, GstCaps * caps)
350 GstPad *pad = GST_BASE_SINK (alsa)->sinkpad;
353 gboolean ret = FALSE;
354 GstAudioRingBufferSpec spec = { 0 };
356 pad_caps = gst_pad_query_caps (pad, caps);
357 if (!pad_caps || gst_caps_is_empty (pad_caps)) {
359 gst_caps_unref (pad_caps);
363 gst_caps_unref (pad_caps);
365 /* If we've not got fixed caps, creating a stream might fail, so let's just
366 * return from here with default acceptcaps behaviour */
367 if (!gst_caps_is_fixed (caps))
370 /* parse helper expects this set, so avoid nasty warning
371 * will be set properly later on anyway */
372 spec.latency_time = GST_SECOND;
373 if (!gst_audio_ring_buffer_parse_caps (&spec, caps))
376 /* Make sure input is framed (one frame per buffer) and can be payloaded */
378 case GST_AUDIO_RING_BUFFER_FORMAT_TYPE_AC3:
379 case GST_AUDIO_RING_BUFFER_FORMAT_TYPE_EAC3:
380 case GST_AUDIO_RING_BUFFER_FORMAT_TYPE_DTS:
381 case GST_AUDIO_RING_BUFFER_FORMAT_TYPE_MPEG:
383 gboolean framed = FALSE, parsed = FALSE;
384 st = gst_caps_get_structure (caps, 0);
386 gst_structure_get_boolean (st, "framed", &framed);
387 gst_structure_get_boolean (st, "parsed", &parsed);
388 if ((!framed && !parsed) || gst_audio_iec61937_frame_size (&spec) <= 0)
397 gst_caps_replace (&spec.caps, NULL);
402 gst_alsasink_query (GstBaseSink * sink, GstQuery * query)
404 GstAlsaSink *alsa = GST_ALSA_SINK (sink);
407 switch (GST_QUERY_TYPE (query)) {
408 case GST_QUERY_ACCEPT_CAPS:
412 gst_query_parse_accept_caps (query, &caps);
413 ret = gst_alsasink_acceptcaps (alsa, caps);
414 gst_query_set_accept_caps_result (query, ret);
419 ret = GST_BASE_SINK_CLASS (parent_class)->query (sink, query);
426 set_hwparams (GstAlsaSink * alsa)
430 snd_pcm_hw_params_t *params, *params_copy;
432 snd_pcm_hw_params_malloc (¶ms);
433 snd_pcm_hw_params_malloc (¶ms_copy);
435 GST_DEBUG_OBJECT (alsa, "Negotiating to %d channels @ %d Hz (format = %s) "
436 "SPDIF (%d)", alsa->channels, alsa->rate,
437 snd_pcm_format_name (alsa->format), alsa->iec958);
439 /* choose all parameters */
440 CHECK (snd_pcm_hw_params_any (alsa->handle, params), no_config);
441 /* set the interleaved read/write format */
442 CHECK (snd_pcm_hw_params_set_access (alsa->handle, params, alsa->access),
444 /* set the sample format */
446 /* Try to use big endian first else fallback to le and swap bytes */
447 if (snd_pcm_hw_params_set_format (alsa->handle, params, alsa->format) < 0) {
448 alsa->format = SND_PCM_FORMAT_S16_LE;
449 alsa->need_swap = TRUE;
450 GST_DEBUG_OBJECT (alsa, "falling back to little endian with swapping");
452 alsa->need_swap = FALSE;
455 CHECK (snd_pcm_hw_params_set_format (alsa->handle, params, alsa->format),
457 /* set the count of channels */
458 CHECK (snd_pcm_hw_params_set_channels (alsa->handle, params, alsa->channels),
460 /* set the stream rate */
462 CHECK (snd_pcm_hw_params_set_rate_near (alsa->handle, params, &rrate, NULL),
464 #ifndef GST_DISABLE_GST_DEBUG
465 /* get and dump some limits */
469 snd_pcm_hw_params_get_buffer_time_min (params, &min, NULL);
470 snd_pcm_hw_params_get_buffer_time_max (params, &max, NULL);
472 GST_DEBUG_OBJECT (alsa, "buffer time %u, min %u, max %u",
473 alsa->buffer_time, min, max);
475 snd_pcm_hw_params_get_period_time_min (params, &min, NULL);
476 snd_pcm_hw_params_get_period_time_max (params, &max, NULL);
478 GST_DEBUG_OBJECT (alsa, "period time %u, min %u, max %u",
479 alsa->period_time, min, max);
481 snd_pcm_hw_params_get_periods_min (params, &min, NULL);
482 snd_pcm_hw_params_get_periods_max (params, &max, NULL);
484 GST_DEBUG_OBJECT (alsa, "periods min %u, max %u", min, max);
487 /* Keep a copy of initial params struct that can be used later */
488 snd_pcm_hw_params_copy (params_copy, params);
490 /* Following pulseaudio's approach in
491 * https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/commit/557c4295107dc7374c850b0bd5331dd35e8fdd0f
492 * we'll try various configuration to set the period time and buffer time as some
493 * driver can be picky on the order of the calls.
495 if (alsa->buffer_time != -1 && alsa->period_time != -1) {
496 if (((err = snd_pcm_hw_params_set_period_time_near (alsa->handle,
497 params, &alsa->period_time, NULL)) >= 0)
499 snd_pcm_hw_params_set_buffer_time_near (alsa->handle,
500 params, &alsa->buffer_time, NULL)) >= 0)) {
501 GST_DEBUG_OBJECT (alsa, "period time %u buffer time %u set correctly",
502 alsa->period_time, alsa->buffer_time);
505 /* Try the new order with previous params struct as current one might
506 have partial settings from the order that was tried unsuccessfully */
507 snd_pcm_hw_params_copy (params, params_copy);
508 if (((err = snd_pcm_hw_params_set_buffer_time_near (alsa->handle,
509 params, &alsa->buffer_time, NULL)) >= 0)
511 snd_pcm_hw_params_set_period_time_near (alsa->handle,
512 params, &alsa->period_time, NULL)) >= 0)) {
513 GST_DEBUG_OBJECT (alsa, "buffer time %u period time %u set correctly",
514 alsa->buffer_time, alsa->period_time);
518 /* now try to configure the period time and buffer time exclusively
519 * if both fail we fall back to the defaults */
520 if (alsa->period_time != -1) {
521 snd_pcm_hw_params_copy (params, params_copy);
522 /* set the period time */
524 snd_pcm_hw_params_set_period_time_near (alsa->handle, params,
525 &alsa->period_time, NULL)) < 0) {
526 GST_DEBUG_OBJECT (alsa, "Unable to set period time %i for playback: %s",
527 alsa->period_time, snd_strerror (err));
529 GST_DEBUG_OBJECT (alsa, "period time %u set correctly",
534 if (alsa->buffer_time != -1) {
535 snd_pcm_hw_params_copy (params, params_copy);
536 /* set the buffer time */
538 snd_pcm_hw_params_set_buffer_time_near (alsa->handle, params,
539 &alsa->buffer_time, NULL)) < 0) {
540 GST_DEBUG_OBJECT (alsa, "Unable to set buffer time %i for playback: %s",
541 alsa->buffer_time, snd_strerror (err));
543 GST_DEBUG_OBJECT (alsa, "buffer time %u set correctly",
549 /* Set buffer size and period size manually for SPDIF */
550 snd_pcm_uframes_t buffer_size = SPDIF_BUFFER_SIZE;
551 snd_pcm_uframes_t period_size = SPDIF_PERIOD_SIZE;
553 CHECK (snd_pcm_hw_params_set_buffer_size_near (alsa->handle, params,
554 &buffer_size), buffer_size);
555 CHECK (snd_pcm_hw_params_set_period_size_near (alsa->handle, params,
556 &period_size, NULL), period_size);
559 /* Set nothing if all above failed */
560 snd_pcm_hw_params_copy (params, params_copy);
561 GST_DEBUG_OBJECT (alsa, "Not setting period time and buffer time");
564 /* write the parameters to device */
565 CHECK (snd_pcm_hw_params (alsa->handle, params), set_hw_params);
566 /* now get the configured values */
567 CHECK (snd_pcm_hw_params_get_buffer_size (params, &alsa->buffer_size),
569 CHECK (snd_pcm_hw_params_get_period_size (params, &alsa->period_size,
572 GST_DEBUG_OBJECT (alsa, "buffer size %lu, period size %lu", alsa->buffer_size,
575 /* Check if hardware supports pause */
576 alsa->hw_support_pause = snd_pcm_hw_params_can_pause (params);
577 GST_DEBUG_OBJECT (alsa, "Hw support pause: %s",
578 alsa->hw_support_pause ? "yes" : "no");
584 GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL),
585 ("Broken configuration for playback: no configurations available: %s",
586 snd_strerror (err)));
591 GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL),
592 ("Access type not available for playback: %s", snd_strerror (err)));
597 GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL),
598 ("Sample format not available for playback: %s", snd_strerror (err)));
605 if ((alsa->channels) == 1)
606 msg = g_strdup (_("Could not open device for playback in mono mode."));
607 if ((alsa->channels) == 2)
608 msg = g_strdup (_("Could not open device for playback in stereo mode."));
609 if ((alsa->channels) > 2)
612 ("Could not open device for playback in %d-channel mode."),
614 GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, ("%s", msg),
615 ("%s", snd_strerror (err)));
621 GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL),
622 ("Rate %iHz not available for playback: %s",
623 alsa->rate, snd_strerror (err)));
628 GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL),
629 ("Unable to get buffer size for playback: %s", snd_strerror (err)));
634 GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL),
635 ("Unable to get period size for playback: %s", snd_strerror (err)));
640 GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL),
641 ("Unable to set hw params for playback: %s", snd_strerror (err)));
645 snd_pcm_hw_params_free (params);
646 snd_pcm_hw_params_free (params_copy);
652 set_swparams (GstAlsaSink * alsa)
655 snd_pcm_sw_params_t *params;
657 snd_pcm_sw_params_malloc (¶ms);
659 /* get the current swparams */
660 CHECK (snd_pcm_sw_params_current (alsa->handle, params), no_config);
661 /* start the transfer when the buffer is almost full: */
662 /* (buffer_size / avail_min) * avail_min */
663 CHECK (snd_pcm_sw_params_set_start_threshold (alsa->handle, params,
664 (alsa->buffer_size / alsa->period_size) * alsa->period_size),
667 /* allow the transfer when at least period_size samples can be processed */
668 CHECK (snd_pcm_sw_params_set_avail_min (alsa->handle, params,
669 alsa->period_size), set_avail);
671 #if GST_CHECK_ALSA_VERSION(1,0,16)
672 /* snd_pcm_sw_params_set_xfer_align() is deprecated, alignment is always 1 */
674 /* align all transfers to 1 sample */
675 CHECK (snd_pcm_sw_params_set_xfer_align (alsa->handle, params, 1), set_align);
678 /* write the parameters to the playback device */
679 CHECK (snd_pcm_sw_params (alsa->handle, params), set_sw_params);
681 snd_pcm_sw_params_free (params);
687 GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL),
688 ("Unable to determine current swparams for playback: %s",
689 snd_strerror (err)));
690 snd_pcm_sw_params_free (params);
695 GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL),
696 ("Unable to set start threshold mode for playback: %s",
697 snd_strerror (err)));
698 snd_pcm_sw_params_free (params);
703 GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL),
704 ("Unable to set avail min for playback: %s", snd_strerror (err)));
705 snd_pcm_sw_params_free (params);
708 #if !GST_CHECK_ALSA_VERSION(1,0,16)
711 GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL),
712 ("Unable to set transfer align for playback: %s", snd_strerror (err)));
713 snd_pcm_sw_params_free (params);
719 GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL),
720 ("Unable to set sw params for playback: %s", snd_strerror (err)));
721 snd_pcm_sw_params_free (params);
727 alsasink_parse_spec (GstAlsaSink * alsa, GstAudioRingBufferSpec * spec)
729 /* Initialize our boolean */
730 alsa->iec958 = FALSE;
732 switch (spec->type) {
733 case GST_AUDIO_RING_BUFFER_FORMAT_TYPE_RAW:
734 switch (GST_AUDIO_INFO_FORMAT (&spec->info)) {
735 case GST_AUDIO_FORMAT_U8:
736 alsa->format = SND_PCM_FORMAT_U8;
738 case GST_AUDIO_FORMAT_S8:
739 alsa->format = SND_PCM_FORMAT_S8;
741 case GST_AUDIO_FORMAT_S16LE:
742 alsa->format = SND_PCM_FORMAT_S16_LE;
744 case GST_AUDIO_FORMAT_S16BE:
745 alsa->format = SND_PCM_FORMAT_S16_BE;
747 case GST_AUDIO_FORMAT_U16LE:
748 alsa->format = SND_PCM_FORMAT_U16_LE;
750 case GST_AUDIO_FORMAT_U16BE:
751 alsa->format = SND_PCM_FORMAT_U16_BE;
753 case GST_AUDIO_FORMAT_S24_32LE:
754 alsa->format = SND_PCM_FORMAT_S24_LE;
756 case GST_AUDIO_FORMAT_S24_32BE:
757 alsa->format = SND_PCM_FORMAT_S24_BE;
759 case GST_AUDIO_FORMAT_U24_32LE:
760 alsa->format = SND_PCM_FORMAT_U24_LE;
762 case GST_AUDIO_FORMAT_U24_32BE:
763 alsa->format = SND_PCM_FORMAT_U24_BE;
765 case GST_AUDIO_FORMAT_S32LE:
766 alsa->format = SND_PCM_FORMAT_S32_LE;
768 case GST_AUDIO_FORMAT_S32BE:
769 alsa->format = SND_PCM_FORMAT_S32_BE;
771 case GST_AUDIO_FORMAT_U32LE:
772 alsa->format = SND_PCM_FORMAT_U32_LE;
774 case GST_AUDIO_FORMAT_U32BE:
775 alsa->format = SND_PCM_FORMAT_U32_BE;
777 case GST_AUDIO_FORMAT_S24LE:
778 alsa->format = SND_PCM_FORMAT_S24_3LE;
780 case GST_AUDIO_FORMAT_S24BE:
781 alsa->format = SND_PCM_FORMAT_S24_3BE;
783 case GST_AUDIO_FORMAT_U24LE:
784 alsa->format = SND_PCM_FORMAT_U24_3LE;
786 case GST_AUDIO_FORMAT_U24BE:
787 alsa->format = SND_PCM_FORMAT_U24_3BE;
789 case GST_AUDIO_FORMAT_S20LE:
790 alsa->format = SND_PCM_FORMAT_S20_3LE;
792 case GST_AUDIO_FORMAT_S20BE:
793 alsa->format = SND_PCM_FORMAT_S20_3BE;
795 case GST_AUDIO_FORMAT_U20LE:
796 alsa->format = SND_PCM_FORMAT_U20_3LE;
798 case GST_AUDIO_FORMAT_U20BE:
799 alsa->format = SND_PCM_FORMAT_U20_3BE;
801 case GST_AUDIO_FORMAT_S18LE:
802 alsa->format = SND_PCM_FORMAT_S18_3LE;
804 case GST_AUDIO_FORMAT_S18BE:
805 alsa->format = SND_PCM_FORMAT_S18_3BE;
807 case GST_AUDIO_FORMAT_U18LE:
808 alsa->format = SND_PCM_FORMAT_U18_3LE;
810 case GST_AUDIO_FORMAT_U18BE:
811 alsa->format = SND_PCM_FORMAT_U18_3BE;
813 case GST_AUDIO_FORMAT_F32LE:
814 alsa->format = SND_PCM_FORMAT_FLOAT_LE;
816 case GST_AUDIO_FORMAT_F32BE:
817 alsa->format = SND_PCM_FORMAT_FLOAT_BE;
819 case GST_AUDIO_FORMAT_F64LE:
820 alsa->format = SND_PCM_FORMAT_FLOAT64_LE;
822 case GST_AUDIO_FORMAT_F64BE:
823 alsa->format = SND_PCM_FORMAT_FLOAT64_BE;
829 case GST_AUDIO_RING_BUFFER_FORMAT_TYPE_A_LAW:
830 alsa->format = SND_PCM_FORMAT_A_LAW;
832 case GST_AUDIO_RING_BUFFER_FORMAT_TYPE_MU_LAW:
833 alsa->format = SND_PCM_FORMAT_MU_LAW;
835 case GST_AUDIO_RING_BUFFER_FORMAT_TYPE_AC3:
836 case GST_AUDIO_RING_BUFFER_FORMAT_TYPE_EAC3:
837 case GST_AUDIO_RING_BUFFER_FORMAT_TYPE_DTS:
838 case GST_AUDIO_RING_BUFFER_FORMAT_TYPE_MPEG:
839 alsa->format = SND_PCM_FORMAT_S16_BE;
846 alsa->rate = GST_AUDIO_INFO_RATE (&spec->info);
847 alsa->channels = GST_AUDIO_INFO_CHANNELS (&spec->info);
848 alsa->buffer_time = spec->buffer_time;
849 alsa->period_time = spec->latency_time;
850 alsa->access = SND_PCM_ACCESS_RW_INTERLEAVED;
852 if (spec->type == GST_AUDIO_RING_BUFFER_FORMAT_TYPE_RAW && alsa->channels < 9)
853 gst_audio_ring_buffer_set_channel_positions (GST_AUDIO_BASE_SINK
854 (alsa)->ringbuffer, alsa_position[alsa->channels - 1]);
866 gst_alsasink_open (GstAudioSink * asink)
871 alsa = GST_ALSA_SINK (asink);
873 /* open in non-blocking mode, we'll use snd_pcm_wait() for space to become
875 CHECK (snd_pcm_open (&alsa->handle, alsa->device, SND_PCM_STREAM_PLAYBACK,
876 SND_PCM_NONBLOCK), open_error);
877 GST_LOG_OBJECT (alsa, "Opened device %s", alsa->device);
885 GST_ELEMENT_ERROR (alsa, RESOURCE, BUSY,
886 (_("Could not open audio device for playback. "
887 "Device is being used by another application.")),
888 ("Device '%s' is busy", alsa->device));
890 GST_ELEMENT_ERROR (alsa, RESOURCE, OPEN_WRITE,
891 (_("Could not open audio device for playback.")),
892 ("Playback open error on device '%s': %s", alsa->device,
893 snd_strerror (err)));
900 gst_alsasink_prepare (GstAudioSink * asink, GstAudioRingBufferSpec * spec)
905 alsa = GST_ALSA_SINK (asink);
908 snd_pcm_close (alsa->handle);
909 alsa->handle = gst_alsa_open_iec958_pcm (GST_OBJECT (alsa), alsa->device);
910 if (G_UNLIKELY (!alsa->handle)) {
915 if (!alsasink_parse_spec (alsa, spec))
918 CHECK (set_hwparams (alsa), hw_params_failed);
919 CHECK (set_swparams (alsa), sw_params_failed);
921 alsa->bpf = GST_AUDIO_INFO_BPF (&spec->info);
922 spec->segsize = alsa->period_size * alsa->bpf;
923 spec->segtotal = alsa->buffer_size / alsa->period_size;
926 snd_output_t *out_buf = NULL;
929 snd_output_buffer_open (&out_buf);
930 snd_pcm_dump_hw_setup (alsa->handle, out_buf);
931 snd_output_buffer_string (out_buf, &msg);
932 GST_DEBUG_OBJECT (alsa, "Hardware setup: \n%s", msg);
933 snd_output_close (out_buf);
934 snd_output_buffer_open (&out_buf);
935 snd_pcm_dump_sw_setup (alsa->handle, out_buf);
936 snd_output_buffer_string (out_buf, &msg);
937 GST_DEBUG_OBJECT (alsa, "Software setup: \n%s", msg);
938 snd_output_close (out_buf);
941 #ifdef SND_CHMAP_API_VERSION
942 alsa_detect_channels_mapping (GST_OBJECT (alsa), alsa->handle, spec,
943 alsa->channels, GST_AUDIO_BASE_SINK (alsa)->ringbuffer);
944 #endif /* SND_CHMAP_API_VERSION */
951 GST_ELEMENT_ERROR (alsa, RESOURCE, OPEN_WRITE, (NULL),
952 ("Could not open IEC958 (SPDIF) device for playback"));
957 GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL),
958 ("Error parsing spec"));
963 GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL),
964 ("Setting of hwparams failed: %s", snd_strerror (err)));
969 GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL),
970 ("Setting of swparams failed: %s", snd_strerror (err)));
976 gst_alsasink_unprepare (GstAudioSink * asink)
980 alsa = GST_ALSA_SINK (asink);
982 snd_pcm_drop (alsa->handle);
983 snd_pcm_hw_free (alsa->handle);
989 gst_alsasink_close (GstAudioSink * asink)
991 GstAlsaSink *alsa = GST_ALSA_SINK (asink);
993 GST_OBJECT_LOCK (asink);
995 snd_pcm_close (alsa->handle);
998 gst_caps_replace (&alsa->cached_caps, NULL);
999 GST_OBJECT_UNLOCK (asink);
1006 * Underrun and suspend recovery
1009 xrun_recovery (GstAlsaSink * alsa, snd_pcm_t * handle, gint err)
1011 GST_WARNING_OBJECT (alsa, "xrun recovery %d: %s", err, g_strerror (-err));
1013 if (err == -EPIPE) { /* under-run */
1014 err = snd_pcm_prepare (handle);
1016 GST_WARNING_OBJECT (alsa,
1017 "Can't recover from underrun, prepare failed: %s",
1018 snd_strerror (err));
1019 gst_audio_base_sink_report_device_failure (GST_AUDIO_BASE_SINK (alsa));
1021 } else if (err == -ESTRPIPE) {
1022 while ((err = snd_pcm_resume (handle)) == -EAGAIN)
1023 g_usleep (100); /* wait until the suspend flag is released */
1026 err = snd_pcm_prepare (handle);
1028 GST_WARNING_OBJECT (alsa,
1029 "Can't recover from suspend, prepare failed: %s",
1030 snd_strerror (err));
1033 gst_audio_base_sink_report_device_failure (GST_AUDIO_BASE_SINK (alsa));
1040 gst_alsasink_write (GstAudioSink * asink, gpointer data, guint length)
1047 alsa = GST_ALSA_SINK (asink);
1049 if (alsa->iec958 && alsa->need_swap) {
1051 guint16 *ptr_tmp = (guint16 *) ptr;
1053 GST_DEBUG_OBJECT (asink, "swapping bytes");
1054 for (i = 0; i < length / 2; i++) {
1055 ptr_tmp[i] = GUINT16_SWAP_LE_BE (ptr_tmp[i]);
1059 GST_LOG_OBJECT (asink, "received audio samples buffer of %u bytes", length);
1061 cptr = length / alsa->bpf;
1063 GST_ALSA_SINK_LOCK (asink);
1065 if (alsa->stop_streaming_threads)
1067 /* start by doing a blocking wait for free space. Set the timeout
1068 * to 4 times the period time */
1069 err = snd_pcm_wait (alsa->handle, (4 * alsa->period_time / 1000));
1071 GST_DEBUG_OBJECT (asink, "wait error, %d", err);
1073 GST_DELAY_SINK_LOCK (asink);
1074 err = snd_pcm_writei (alsa->handle, ptr, cptr);
1075 GST_DELAY_SINK_UNLOCK (asink);
1079 GST_DEBUG_OBJECT (asink, "Write error: %s (%d)", snd_strerror (err), err);
1080 if (err == -EAGAIN) {
1081 /* will continue out of the if/else group */
1082 } else if (err == -ENODEV) {
1083 goto device_disappeared;
1084 } else if (xrun_recovery (alsa, alsa->handle, err) < 0) {
1088 /* Unlock so that _reset() can run and break an otherwise infinit loop
1090 GST_ALSA_SINK_UNLOCK (asink);
1092 GST_ALSA_SINK_LOCK (asink);
1094 } else if (err == 0 && alsa->hw_support_pause) {
1095 /* We might be already paused, if so, just bail */
1096 if (snd_pcm_state (alsa->handle) == SND_PCM_STATE_PAUSED)
1100 GST_DEBUG_OBJECT (asink, "written %d frames out of %d", err, cptr);
1101 ptr += snd_pcm_frames_to_bytes (alsa->handle, err);
1104 GST_ALSA_SINK_UNLOCK (asink);
1106 return length - (cptr * alsa->bpf);
1110 GST_ALSA_SINK_UNLOCK (asink);
1111 return length; /* skip one period */
1115 GST_ELEMENT_ERROR (asink, RESOURCE, WRITE,
1116 (_("Error outputting to audio device. "
1117 "The device has been disconnected.")), (NULL));
1123 gst_alsasink_delay (GstAudioSink * asink)
1126 snd_pcm_sframes_t delay;
1129 alsa = GST_ALSA_SINK (asink);
1131 GST_DELAY_SINK_LOCK (asink);
1132 if (alsa->is_paused == TRUE) {
1133 delay = alsa->pos_in_buffer;
1134 alsa->is_paused = FALSE;
1135 alsa->after_paused = TRUE;
1137 if (alsa->after_paused == TRUE) {
1138 delay = alsa->pos_in_buffer;
1139 alsa->after_paused = FALSE;
1141 res = snd_pcm_delay (alsa->handle, &delay);
1144 GST_DELAY_SINK_UNLOCK (asink);
1145 if (G_UNLIKELY (res < 0)) {
1146 /* on errors, report 0 delay */
1147 GST_DEBUG_OBJECT (alsa, "snd_pcm_delay returned %d", res);
1150 if (G_UNLIKELY (delay < 0)) {
1151 /* make sure we never return a negative delay */
1152 GST_WARNING_OBJECT (alsa, "snd_pcm_delay returned negative delay");
1160 gst_alsasink_pause (GstAudioSink * asink)
1164 snd_pcm_sframes_t delay;
1166 alsa = GST_ALSA_SINK (asink);
1168 if (alsa->hw_support_pause == TRUE) {
1169 GST_ALSA_SINK_LOCK (asink);
1170 snd_pcm_delay (alsa->handle, &delay);
1171 alsa->pos_in_buffer = delay;
1172 CHECK (snd_pcm_pause (alsa->handle, 1), pause_error);
1173 GST_DEBUG_OBJECT (alsa, "pause done");
1174 alsa->is_paused = TRUE;
1175 alsa->stop_streaming_threads = TRUE;
1176 GST_ALSA_SINK_UNLOCK (asink);
1178 gst_alsasink_stop (asink);
1185 GST_ERROR_OBJECT (alsa, "alsa-pause: pcm pause error: %s",
1186 snd_strerror (err));
1187 GST_ALSA_SINK_UNLOCK (asink);
1193 gst_alsasink_resume (GstAudioSink * asink)
1198 alsa = GST_ALSA_SINK (asink);
1200 if (alsa->hw_support_pause == TRUE) {
1201 GST_ALSA_SINK_LOCK (asink);
1202 CHECK (snd_pcm_pause (alsa->handle, 0), resume_error);
1203 GST_DEBUG_OBJECT (alsa, "resume done");
1204 GST_ALSA_SINK_UNLOCK (asink);
1207 alsa->stop_streaming_threads = FALSE;
1212 GST_ERROR_OBJECT (alsa, "alsa-resume: pcm resume error: %s",
1213 snd_strerror (err));
1214 GST_ALSA_SINK_UNLOCK (asink);
1220 gst_alsasink_stop (GstAudioSink * asink)
1225 alsa = GST_ALSA_SINK (asink);
1227 GST_ALSA_SINK_LOCK (asink);
1228 GST_DEBUG_OBJECT (alsa, "drop");
1229 CHECK (snd_pcm_drop (alsa->handle), drop_error);
1230 GST_DEBUG_OBJECT (alsa, "prepare");
1231 CHECK (snd_pcm_prepare (alsa->handle), prepare_error);
1232 GST_DEBUG_OBJECT (alsa, "stop done");
1233 alsa->stop_streaming_threads = TRUE;
1234 GST_ALSA_SINK_UNLOCK (asink);
1241 GST_ERROR_OBJECT (alsa, "alsa-stop: pcm drop error: %s",
1242 snd_strerror (err));
1243 GST_ALSA_SINK_UNLOCK (asink);
1248 GST_ERROR_OBJECT (alsa, "alsa-stop: pcm prepare error: %s",
1249 snd_strerror (err));
1250 GST_ALSA_SINK_UNLOCK (asink);
1256 gst_alsasink_payload (GstAudioBaseSink * sink, GstBuffer * buf)
1260 alsa = GST_ALSA_SINK (sink);
1265 GstMapInfo iinfo, oinfo;
1267 framesize = gst_audio_iec61937_frame_size (&sink->ringbuffer->spec);
1271 out = gst_buffer_new_and_alloc (framesize);
1273 gst_buffer_map (buf, &iinfo, GST_MAP_READ);
1274 gst_buffer_map (out, &oinfo, GST_MAP_WRITE);
1276 if (!gst_audio_iec61937_payload (iinfo.data, iinfo.size,
1277 oinfo.data, oinfo.size, &sink->ringbuffer->spec, G_BIG_ENDIAN)) {
1278 gst_buffer_unmap (buf, &iinfo);
1279 gst_buffer_unmap (out, &oinfo);
1280 gst_buffer_unref (out);
1284 gst_buffer_unmap (buf, &iinfo);
1285 gst_buffer_unmap (out, &oinfo);
1287 gst_buffer_copy_into (out, buf, GST_BUFFER_COPY_METADATA, 0, -1);
1291 return gst_buffer_ref (buf);