summaryrefslogtreecommitdiffstats
path: root/sys/osxaudio/gstosxaudiosrc.c
diff options
context:
space:
mode:
authorMichael Smith <msmith@xiph.org>2008-08-26 21:13:08 +0000
committerMichael Smith <msmith@xiph.org>2008-08-26 21:13:08 +0000
commit192c1b942b5a727b03223869e7213af1941b0d5d (patch)
tree977ed239522f2b38c229710fd952293bc26b8119 /sys/osxaudio/gstosxaudiosrc.c
parent2ea5c05241edb2ca63967c3056a5ee3347bce576 (diff)
sys/osxaudio/: Rewrite caps setting and ring buffer initialisation.
Original commit message from CVS: * sys/osxaudio/Makefile.am: * sys/osxaudio/gstosxaudio.c: * sys/osxaudio/gstosxaudiosink.c: * sys/osxaudio/gstosxaudiosink.h: * sys/osxaudio/gstosxaudiosrc.c: * sys/osxaudio/gstosxaudiosrc.h: * sys/osxaudio/gstosxringbuffer.c: * sys/osxaudio/gstosxringbuffer.h: Rewrite caps setting and ring buffer initialisation. Previously we never told CoreAudio what format we were going to send it, so it only worked due to luck, and not at all on some hardware. Now we explicitly advertise what formats the hardware supports, and then configure the selected one correctly.
Diffstat (limited to 'sys/osxaudio/gstosxaudiosrc.c')
-rw-r--r--sys/osxaudio/gstosxaudiosrc.c123
1 files changed, 96 insertions, 27 deletions
diff --git a/sys/osxaudio/gstosxaudiosrc.c b/sys/osxaudio/gstosxaudiosrc.c
index 0a543ae5..359eb7a7 100644
--- a/sys/osxaudio/gstosxaudiosrc.c
+++ b/sys/osxaudio/gstosxaudiosrc.c
@@ -1,6 +1,7 @@
/*
* GStreamer
* Copyright 2005,2006 Zaheer Abbas Merali <zaheerabbas at merali dot org>
+ * 2008 Pioneers of the Inevitable <songbird@songbirdnest.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -92,7 +93,8 @@ static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
"endianness = (int) {" G_STRINGIFY (G_BYTE_ORDER) " }, "
"signed = (boolean) { TRUE }, "
"width = (int) 32, "
- "depth = (int) 32, " "rate = (int) 44100, " "channels = (int) 2")
+ "depth = (int) 32, "
+ "rate = (int) [1, MAX], " "channels = (int) [1, 2]")
);
static void gst_osx_audio_src_set_property (GObject * object, guint prop_id,
@@ -103,13 +105,13 @@ static void gst_osx_audio_src_get_property (GObject * object, guint prop_id,
static GstRingBuffer *gst_osx_audio_src_create_ringbuffer (GstBaseAudioSrc *
src);
-/*static GstCaps* gst_osx_audio_sink_getcaps (GstBaseSink * bsrc);*/
static void gst_osx_audio_src_osxelement_init (gpointer g_iface,
gpointer iface_data);
OSStatus gst_osx_audio_src_io_proc (AudioDeviceID inDevice,
const AudioTimeStamp * inNow, const AudioBufferList * inInputData,
const AudioTimeStamp * inInputTime, AudioBufferList * outOutputData,
const AudioTimeStamp * inOutputTime, void *inClientData);
+static void gst_osx_audio_src_select_device (GstOsxAudioSrc * osxsrc);
static void
gst_osx_audio_src_osxelement_do_init (GType type)
@@ -178,11 +180,11 @@ gst_osx_audio_src_class_init (GstOsxAudioSrcClass * klass)
static void
gst_osx_audio_src_init (GstOsxAudioSrc * src, GstOsxAudioSrcClass * gclass)
{
-/* GstElementClass *klass = GST_ELEMENT_GET_CLASS (sink); */
+/* GstElementClass *klass = GST_ELEMENT_GET_CLASS (src); */
gst_base_src_set_live (GST_BASE_SRC (src), TRUE);
- src->ringbuffer = NULL;
- GST_DEBUG ("Initialising object");
- gst_osx_audio_src_create_ringbuffer (GST_BASE_AUDIO_SRC (src));
+
+ src->device_id = kAudioDeviceUnknown;
+ src->stream_id = kAudioStreamUnknown;
}
static void
@@ -193,8 +195,7 @@ gst_osx_audio_src_set_property (GObject * object, guint prop_id,
switch (prop_id) {
case ARG_DEVICE:
- if (src->ringbuffer)
- src->ringbuffer->device_id = g_value_get_int (value);
+ src->device_id = g_value_get_int (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -207,14 +208,10 @@ gst_osx_audio_src_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec)
{
GstOsxAudioSrc *src = GST_OSX_AUDIO_SRC (object);
- int val = 0;
switch (prop_id) {
case ARG_DEVICE:
- if (src->ringbuffer)
- val = src->ringbuffer->device_id;
-
- g_value_set_int (value, val);
+ g_value_set_int (value, src->device_id);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -225,29 +222,32 @@ gst_osx_audio_src_get_property (GObject * object, guint prop_id,
/* GstElement vmethod implementations */
-/* GstBaseAudioSink vmethod implementations */
+/* GstBaseAudioSrc vmethod implementations */
static GstRingBuffer *
gst_osx_audio_src_create_ringbuffer (GstBaseAudioSrc * src)
{
GstOsxAudioSrc *osxsrc;
OSStatus status;
UInt32 propertySize;
+ GstOsxRingBuffer *ringbuffer;
osxsrc = GST_OSX_AUDIO_SRC (src);
- if (!osxsrc->ringbuffer) {
- GST_DEBUG ("Creating ringbuffer");
- osxsrc->ringbuffer = g_object_new (GST_TYPE_OSX_RING_BUFFER, NULL);
- /* change the device to the Default Input Device */
- propertySize = sizeof (osxsrc->ringbuffer->device_id);
- status = AudioHardwareGetProperty (kAudioHardwarePropertyDefaultInputDevice,
- &propertySize, &osxsrc->ringbuffer->device_id);
- GST_DEBUG ("osx src 0x%p element 0x%p ioproc 0x%p", osxsrc,
- GST_OSX_AUDIO_ELEMENT_GET_INTERFACE (osxsrc),
- (void *) gst_osx_audio_src_io_proc);
- osxsrc->ringbuffer->element = GST_OSX_AUDIO_ELEMENT_GET_INTERFACE (osxsrc);
- }
- return GST_RING_BUFFER (osxsrc->ringbuffer);
+ gst_osx_audio_src_select_device (osxsrc);
+
+ GST_DEBUG ("Creating ringbuffer");
+ ringbuffer = g_object_new (GST_TYPE_OSX_RING_BUFFER, NULL);
+
+ /* change the device to the Default Input Device */
+ GST_DEBUG ("osx src 0x%p element 0x%p ioproc 0x%p", osxsrc,
+ GST_OSX_AUDIO_ELEMENT_GET_INTERFACE (osxsrc),
+ (void *) gst_osx_audio_src_io_proc);
+
+ ringbuffer->element = GST_OSX_AUDIO_ELEMENT_GET_INTERFACE (osxsrc);
+ ringbuffer->device_id = osxsrc->device_id;
+ ringbuffer->stream_id = osxsrc->stream_id;
+
+ return GST_RING_BUFFER (ringbuffer);
}
OSStatus
@@ -284,3 +284,72 @@ gst_osx_audio_src_osxelement_init (gpointer g_iface, gpointer iface_data)
iface->io_proc = gst_osx_audio_src_io_proc;
}
+
+static void
+gst_osx_audio_src_select_device (GstOsxAudioSrc * osxsrc)
+{
+ OSStatus status;
+ UInt32 propertySize;
+
+ if (osxsrc->device_id == kAudioDeviceUnknown) {
+ GST_DEBUG_OBJECT (osxsrc, "Selecting device for OSXAudioSrc");
+ propertySize = sizeof (osxsrc->device_id);
+ status = AudioHardwareGetProperty (kAudioHardwarePropertyDefaultInputDevice,
+ &propertySize, &osxsrc->device_id);
+
+ if (status)
+ GST_WARNING_OBJECT (osxsrc,
+ "AudioHardwareGetProperty returned %d", (int) status);
+ else
+ GST_DEBUG_OBJECT (osxsrc, "AudioHardwareGetProperty returned 0");
+
+ if (osxsrc->device_id == kAudioDeviceUnknown)
+ GST_WARNING_OBJECT (osxsrc,
+ "AudioHardwareGetProperty: device_id is kAudioDeviceUnknown");
+
+ GST_DEBUG_OBJECT (osxsrc, "AudioHardwareGetProperty: device_id is %lu",
+ (long) osxsrc->device_id);
+ }
+
+ if (osxsrc->stream_id == kAudioStreamUnknown) {
+ AudioStreamID *streams;
+
+ GST_DEBUG_OBJECT (osxsrc, "Getting streamid");
+ status = AudioDeviceGetPropertyInfo (osxsrc->device_id, 0, /* Master channel */
+ FALSE, /* isInput */
+ kAudioDevicePropertyStreams, &propertySize, NULL);
+
+ if (status) {
+ GST_WARNING_OBJECT (osxsrc,
+ "AudioDeviceGetProperty returned %d", (int) status);
+ return;
+ }
+
+ GST_DEBUG_OBJECT (osxsrc,
+ "Getting available streamids from %d (%d bytes)",
+ (int) (propertySize / sizeof (AudioStreamID)), propertySize);
+ streams = g_malloc (propertySize);
+ status = AudioDeviceGetProperty (osxsrc->device_id, 0, /* Master channel */
+ FALSE, /* isInput */
+ kAudioDevicePropertyStreams, &propertySize, streams);
+
+ if (status) {
+ GST_WARNING_OBJECT (osxsrc,
+ "AudioDeviceGetProperty returned %d", (int) status);
+ g_free (streams);
+ return;
+ }
+
+ GST_DEBUG_OBJECT (osxsrc, "Getting streamid from %d (%d bytes)",
+ (int) (propertySize / sizeof (AudioStreamID)), propertySize);
+
+ if (propertySize >= sizeof (AudioStreamID)) {
+ osxsrc->stream_id = streams[0];
+ GST_DEBUG_OBJECT (osxsrc, "Selected stream %d of %d: %d", 0,
+ (int) (propertySize / sizeof (AudioStreamID)),
+ (int) osxsrc->stream_id);
+ }
+
+ g_free (streams);
+ }
+}