2 * GStreamer - SunAudio source
3 * Copyright (C) 2005,2006 Sun Microsystems, Inc.,
4 * Brian Cameron <brian.cameron@sun.com>
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
18 * You should have received a copy of the GNU Library General Public
19 * License along with this library; if not, write to the
20 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 * Boston, MA 02111-1307, USA.
25 * SECTION:element-sunaudiosrc
27 * sunaudiosrc is an audio source designed to work with the Sun Audio
28 * interface available in Solaris.
31 * <title>Example launch line</title>
33 * gst-launch sunaudiosrc ! wavenc ! filesink location=audio.wav
46 #include <sys/mixer.h>
48 #include "gstsunaudiosrc.h"
50 GST_DEBUG_CATEGORY_EXTERN (sunaudio_debug);
51 #define GST_CAT_DEFAULT sunaudio_debug
53 static void gst_sunaudiosrc_base_init (gpointer g_class);
54 static void gst_sunaudiosrc_class_init (GstSunAudioSrcClass * klass);
55 static void gst_sunaudiosrc_init (GstSunAudioSrc * sunaudiosrc,
56 GstSunAudioSrcClass * g_class);
57 static void gst_sunaudiosrc_dispose (GObject * object);
59 static void gst_sunaudiosrc_set_property (GObject * object, guint prop_id,
60 const GValue * value, GParamSpec * pspec);
61 static void gst_sunaudiosrc_get_property (GObject * object, guint prop_id,
62 GValue * value, GParamSpec * pspec);
64 static GstCaps *gst_sunaudiosrc_getcaps (GstBaseSrc * bsrc);
66 static gboolean gst_sunaudiosrc_open (GstAudioSrc * asrc);
67 static gboolean gst_sunaudiosrc_close (GstAudioSrc * asrc);
68 static gboolean gst_sunaudiosrc_prepare (GstAudioSrc * asrc,
69 GstRingBufferSpec * spec);
70 static gboolean gst_sunaudiosrc_unprepare (GstAudioSrc * asrc);
71 static guint gst_sunaudiosrc_read (GstAudioSrc * asrc, gpointer data,
73 static guint gst_sunaudiosrc_delay (GstAudioSrc * asrc);
74 static void gst_sunaudiosrc_reset (GstAudioSrc * asrc);
76 #define DEFAULT_DEVICE "/dev/audio"
84 GST_BOILERPLATE_WITH_INTERFACE (GstSunAudioSrc, gst_sunaudiosrc,
85 GstAudioSrc, GST_TYPE_AUDIO_SRC, GstMixer, GST_TYPE_MIXER, gst_sunaudiosrc);
87 GST_IMPLEMENT_SUNAUDIO_MIXER_CTRL_METHODS (GstSunAudioSrc, gst_sunaudiosrc);
89 static GstStaticPadTemplate gst_sunaudiosrc_factory =
90 GST_STATIC_PAD_TEMPLATE ("src",
93 GST_STATIC_CAPS ("audio/x-raw-int, "
94 "endianness = (int) BYTE_ORDER, "
95 "signed = (boolean) TRUE, " "width = (int) 16, " "depth = (int) 16, "
96 /* [5510,48000] seems to be a Solaris limit */
97 "rate = (int) [ 5510, 48000 ], " "channels = (int) [ 1, 2 ]")
101 gst_sunaudiosrc_dispose (GObject * object)
103 G_OBJECT_CLASS (parent_class)->dispose (object);
107 gst_sunaudiosrc_base_init (gpointer g_class)
109 GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
111 gst_element_class_add_pad_template (element_class,
112 gst_static_pad_template_get (&gst_sunaudiosrc_factory));
113 gst_element_class_set_details_simple (element_class, "Sun Audio Source",
115 "Audio source for Sun Audio devices",
116 "Brian Cameron <brian.cameron@sun.com>");
120 gst_sunaudiosrc_class_init (GstSunAudioSrcClass * klass)
122 GObjectClass *gobject_class;
123 GstElementClass *gstelement_class;
124 GstBaseSrcClass *gstbasesrc_class;
125 GstBaseAudioSrcClass *gstbaseaudiosrc_class;
126 GstAudioSrcClass *gstaudiosrc_class;
128 gobject_class = (GObjectClass *) klass;
129 gstelement_class = (GstElementClass *) klass;
130 gstbasesrc_class = (GstBaseSrcClass *) klass;
131 gstbaseaudiosrc_class = (GstBaseAudioSrcClass *) klass;
132 gstaudiosrc_class = (GstAudioSrcClass *) klass;
134 gobject_class->dispose = gst_sunaudiosrc_dispose;
135 gobject_class->get_property = gst_sunaudiosrc_get_property;
136 gobject_class->set_property = gst_sunaudiosrc_set_property;
138 gstbasesrc_class->get_caps = GST_DEBUG_FUNCPTR (gst_sunaudiosrc_getcaps);
140 gstaudiosrc_class->open = GST_DEBUG_FUNCPTR (gst_sunaudiosrc_open);
141 gstaudiosrc_class->prepare = GST_DEBUG_FUNCPTR (gst_sunaudiosrc_prepare);
142 gstaudiosrc_class->unprepare = GST_DEBUG_FUNCPTR (gst_sunaudiosrc_unprepare);
143 gstaudiosrc_class->close = GST_DEBUG_FUNCPTR (gst_sunaudiosrc_close);
144 gstaudiosrc_class->read = GST_DEBUG_FUNCPTR (gst_sunaudiosrc_read);
145 gstaudiosrc_class->delay = GST_DEBUG_FUNCPTR (gst_sunaudiosrc_delay);
146 gstaudiosrc_class->reset = GST_DEBUG_FUNCPTR (gst_sunaudiosrc_reset);
148 g_object_class_install_property (gobject_class, PROP_DEVICE,
149 g_param_spec_string ("device", "Device",
150 "SunAudio device (usually /dev/audio)", DEFAULT_DEVICE,
155 gst_sunaudiosrc_init (GstSunAudioSrc * sunaudiosrc,
156 GstSunAudioSrcClass * g_class)
158 const char *audiodev;
160 GST_DEBUG_OBJECT (sunaudiosrc, "initializing sunaudiosrc");
162 sunaudiosrc->fd = -1;
164 audiodev = g_getenv ("AUDIODEV");
165 if (audiodev == NULL)
166 audiodev = DEFAULT_DEVICE;
167 sunaudiosrc->device = g_strdup (audiodev);
171 gst_sunaudiosrc_set_property (GObject * object, guint prop_id,
172 const GValue * value, GParamSpec * pspec)
174 GstSunAudioSrc *sunaudiosrc;
176 sunaudiosrc = GST_SUNAUDIO_SRC (object);
180 if (sunaudiosrc->device)
181 g_free (sunaudiosrc->device);
182 sunaudiosrc->device = g_value_dup_string (value);
185 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
191 gst_sunaudiosrc_get_property (GObject * object, guint prop_id,
192 GValue * value, GParamSpec * pspec)
194 GstSunAudioSrc *sunaudiosrc;
196 sunaudiosrc = GST_SUNAUDIO_SRC (object);
200 g_value_set_string (value, sunaudiosrc->device);
203 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
209 gst_sunaudiosrc_getcaps (GstBaseSrc * bsrc)
211 GstPadTemplate *pad_template;
212 GstCaps *caps = NULL;
213 GstSunAudioSrc *sunaudiosrc = GST_SUNAUDIO_SRC (bsrc);
215 GST_DEBUG_OBJECT (sunaudiosrc, "getcaps called");
217 pad_template = gst_static_pad_template_get (&gst_sunaudiosrc_factory);
218 caps = gst_caps_copy (gst_pad_template_get_caps (pad_template));
220 gst_object_unref (pad_template);
226 gst_sunaudiosrc_open (GstAudioSrc * asrc)
228 GstSunAudioSrc *sunaudiosrc = GST_SUNAUDIO_SRC (asrc);
231 fd = open (sunaudiosrc->device, O_RDONLY);
234 GST_ELEMENT_ERROR (sunaudiosrc, RESOURCE, OPEN_READ, (NULL),
235 ("can't open connection to Sun Audio device %s", sunaudiosrc->device));
240 sunaudiosrc->fd = fd;
242 ret = ioctl (fd, AUDIO_GETDEV, &sunaudiosrc->dev);
244 GST_ELEMENT_ERROR (sunaudiosrc, RESOURCE, SETTINGS, (NULL), ("%s",
249 GST_DEBUG_OBJECT (sunaudiosrc, "name %s", sunaudiosrc->dev.name);
250 GST_DEBUG_OBJECT (sunaudiosrc, "version %s", sunaudiosrc->dev.version);
251 GST_DEBUG_OBJECT (sunaudiosrc, "config %s", sunaudiosrc->dev.config);
253 ret = ioctl (fd, AUDIO_GETINFO, &sunaudiosrc->info);
255 GST_ELEMENT_ERROR (sunaudiosrc, RESOURCE, SETTINGS, (NULL), ("%s",
260 GST_DEBUG_OBJECT (sunaudiosrc, "monitor_gain %d",
261 sunaudiosrc->info.monitor_gain);
262 GST_DEBUG_OBJECT (sunaudiosrc, "output_muted %d",
263 sunaudiosrc->info.output_muted);
264 GST_DEBUG_OBJECT (sunaudiosrc, "hw_features %08x",
265 sunaudiosrc->info.hw_features);
266 GST_DEBUG_OBJECT (sunaudiosrc, "sw_features %08x",
267 sunaudiosrc->info.sw_features);
268 GST_DEBUG_OBJECT (sunaudiosrc, "sw_features_enabled %08x",
269 sunaudiosrc->info.sw_features_enabled);
271 if (!sunaudiosrc->mixer) {
272 const char *audiodev;
274 audiodev = g_getenv ("AUDIODEV");
275 if (audiodev == NULL) {
276 sunaudiosrc->mixer = gst_sunaudiomixer_ctrl_new ("/dev/audioctl");
278 gchar *device = g_strdup_printf ("%sctl", audiodev);
280 sunaudiosrc->mixer = gst_sunaudiomixer_ctrl_new (device);
289 gst_sunaudiosrc_close (GstAudioSrc * asrc)
291 GstSunAudioSrc *sunaudiosrc = GST_SUNAUDIO_SRC (asrc);
293 close (sunaudiosrc->fd);
294 sunaudiosrc->fd = -1;
296 if (sunaudiosrc->mixer) {
297 gst_sunaudiomixer_ctrl_free (sunaudiosrc->mixer);
298 sunaudiosrc->mixer = NULL;
305 gst_sunaudiosrc_prepare (GstAudioSrc * asrc, GstRingBufferSpec * spec)
307 GstSunAudioSrc *sunaudiosrc = GST_SUNAUDIO_SRC (asrc);
310 GstSunAudioMixerCtrl *mixer;
311 struct audio_info audioinfo;
313 ret = ioctl (sunaudiosrc->fd, AUDIO_GETINFO, &ainfo);
315 GST_ELEMENT_ERROR (sunaudiosrc, RESOURCE, SETTINGS, (NULL), ("%s",
320 if (spec->width != 16)
323 AUDIO_INITINFO (&ainfo);
325 ainfo.record.sample_rate = spec->rate;
326 ainfo.record.precision = spec->width;
327 ainfo.record.channels = spec->channels;
328 ainfo.record.encoding = AUDIO_ENCODING_LINEAR;
329 ainfo.record.buffer_size = spec->buffer_time;
331 mixer = sunaudiosrc->mixer;
333 if (ioctl (mixer->mixer_fd, AUDIO_GETINFO, &audioinfo) < 0) {
334 g_warning ("Error getting audio device volume");
336 ainfo.record.port = audioinfo.record.port;
337 ainfo.record.gain = audioinfo.record.gain;
338 ainfo.record.balance = audioinfo.record.balance;
341 spec->segtotal = spec->buffer_time / 128;
343 spec->silence_sample[0] = 0;
344 spec->silence_sample[1] = 0;
345 spec->silence_sample[2] = 0;
346 spec->silence_sample[3] = 0;
348 ret = ioctl (sunaudiosrc->fd, AUDIO_SETINFO, &ainfo);
350 GST_ELEMENT_ERROR (sunaudiosrc, RESOURCE, SETTINGS, (NULL), ("%s",
356 ioctl (sunaudiosrc->fd, I_FLUSH, FLUSHR);
362 gst_sunaudiosrc_unprepare (GstAudioSrc * asrc)
368 gst_sunaudiosrc_read (GstAudioSrc * asrc, gpointer data, guint length)
370 return read (GST_SUNAUDIO_SRC (asrc)->fd, data, length);
374 gst_sunaudiosrc_delay (GstAudioSrc * asrc)
380 gst_sunaudiosrc_reset (GstAudioSrc * asrc)
382 /* Get current values */
383 GstSunAudioSrc *sunaudiosrc = GST_SUNAUDIO_SRC (asrc);
387 ret = ioctl (sunaudiosrc->fd, AUDIO_GETINFO, &ainfo);
390 * Should never happen, but if we couldn't getinfo, then no point
393 GST_ELEMENT_ERROR (sunaudiosrc, RESOURCE, SETTINGS, (NULL), ("%s",
399 * Pause the audio - so audio stops playing immediately rather than
400 * waiting for the ringbuffer to empty.
402 ainfo.record.pause = !NULL;
403 ret = ioctl (sunaudiosrc->fd, AUDIO_SETINFO, &ainfo);
405 GST_ELEMENT_ERROR (sunaudiosrc, RESOURCE, SETTINGS, (NULL), ("%s",
409 /* Flush the audio */
410 ret = ioctl (sunaudiosrc->fd, I_FLUSH, FLUSHR);
412 GST_ELEMENT_ERROR (sunaudiosrc, RESOURCE, SETTINGS, (NULL), ("%s",
416 /* unpause the audio */
417 ainfo.record.pause = NULL;
418 ret = ioctl (sunaudiosrc->fd, AUDIO_SETINFO, &ainfo);
420 GST_ELEMENT_ERROR (sunaudiosrc, RESOURCE, SETTINGS, (NULL), ("%s",