summaryrefslogtreecommitdiffstats
path: root/sys/osxaudio
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
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')
-rw-r--r--sys/osxaudio/Makefile.am3
-rw-r--r--sys/osxaudio/gstosxaudio.c23
-rw-r--r--sys/osxaudio/gstosxaudiosink.c216
-rw-r--r--sys/osxaudio/gstosxaudiosink.h3
-rw-r--r--sys/osxaudio/gstosxaudiosrc.c123
-rw-r--r--sys/osxaudio/gstosxaudiosrc.h3
-rw-r--r--sys/osxaudio/gstosxringbuffer.c88
-rw-r--r--sys/osxaudio/gstosxringbuffer.h1
8 files changed, 324 insertions, 136 deletions
diff --git a/sys/osxaudio/Makefile.am b/sys/osxaudio/Makefile.am
index 1b0e4875..8882dea2 100644
--- a/sys/osxaudio/Makefile.am
+++ b/sys/osxaudio/Makefile.am
@@ -3,7 +3,8 @@ plugin_LTLIBRARIES = libgstosxaudio.la
libgstosxaudio_la_SOURCES = gstosxringbuffer.c \
gstosxaudioelement.c \
gstosxaudiosink.c \
- gstosxaudiosrc.c
+ gstosxaudiosrc.c \
+ gstosxaudio.c
libgstosxaudio_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) \
-Wno-deprecated-declarations
diff --git a/sys/osxaudio/gstosxaudio.c b/sys/osxaudio/gstosxaudio.c
index 8a79bed2..89232842 100644
--- a/sys/osxaudio/gstosxaudio.c
+++ b/sys/osxaudio/gstosxaudio.c
@@ -1,6 +1,7 @@
/* GStreamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
- * Copyright (C) 2007 Pioneers of the Inevitable <songbird@songbirdnest.com>
+ * Copyright (C) 2007,2008 Pioneers of the Inevitable <songbird@songbirdnest.com>
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
@@ -16,7 +17,8 @@
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
- * The development of this code was made possible due to the involvement of Pioneers of the * Inevitable, the creators of the Songbird Music player
+ * The development of this code was made possible due to the involvement of
+ * Pioneers of the Inevitable, the creators of the Songbird Music player
*
*/
@@ -49,29 +51,20 @@
#include "gstosxaudioelement.h"
#include "gstosxaudiosink.h"
#include "gstosxaudiosrc.h"
-extern gchar *__gst_osxaudio_plugin_dir;
-
-GST_DEBUG_CATEGORY (osxaudio_debug);
static gboolean
plugin_init (GstPlugin * plugin)
{
- if (!gst_library_load ("gstaudio"))
- return FALSE;
-
- if (!gst_element_register (plugin, "osxaudiosink", GST_RANK_PRIMARY,
- GST_TYPE_OSXAUDIOSINK)) {
+ if (!gst_element_register (plugin, "fixedosxaudiosink", GST_RANK_PRIMARY + 1,
+ GST_TYPE_OSX_AUDIO_SINK)) {
return FALSE;
}
- if (!gst_element_register (plugin, "osxaudiosrc", GST_RANK_PRIMARY,
- GST_TYPE_OSXAUDIOSRC)) {
+ if (!gst_element_register (plugin, "fixedosxaudiosrc", GST_RANK_PRIMARY + 1,
+ GST_TYPE_OSX_AUDIO_SRC)) {
return FALSE;
}
- GST_DEBUG_CATEGORY_INIT (osxaudio_debug, "osx", 0, "OSX audio elements");
-
-
return TRUE;
}
diff --git a/sys/osxaudio/gstosxaudiosink.c b/sys/osxaudio/gstosxaudiosink.c
index 222056c8..5f67bb7b 100644
--- a/sys/osxaudio/gstosxaudiosink.c
+++ b/sys/osxaudio/gstosxaudiosink.c
@@ -41,8 +41,8 @@
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
- * The development of this code was made possible due to the involvement of Pioneers of i
- * the Inevitable, the creators of the Songbird Music player
+ * The development of this code was made possible due to the involvement of
+ * Pioneers of the Inevitable, the creators of the Songbird Music player.
*
*/
@@ -65,6 +65,7 @@
#include <gst/gst.h>
#include <CoreAudio/CoreAudio.h>
+#include <CoreAudio/AudioHardware.h>
#include "gstosxaudiosink.h"
#include "gstosxaudiosrc.h"
@@ -99,7 +100,8 @@ static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
"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_sink_set_property (GObject * object, guint prop_id,
@@ -108,16 +110,16 @@ static void gst_osx_audio_sink_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
static GstCaps *gst_osx_audio_sink_getcaps (GstBaseSink * sink);
-
static GstRingBuffer *gst_osx_audio_sink_create_ringbuffer (GstBaseAudioSink *
sink);
-/*static GstCaps* gst_osx_audio_sink_getcaps (GstBaseSink * bsink);*/
static void gst_osx_audio_sink_osxelement_init (gpointer g_iface,
gpointer iface_data);
OSStatus gst_osx_audio_sink_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_sink_select_device (GstOsxAudioSink * osxsink);
+
static void
gst_osx_audio_sink_osxelement_do_init (GType type)
{
@@ -189,10 +191,10 @@ static void
gst_osx_audio_sink_init (GstOsxAudioSink * sink, GstOsxAudioSinkClass * gclass)
{
/* GstElementClass *klass = GST_ELEMENT_GET_CLASS (sink); */
- sink->ringbuffer = NULL;
GST_DEBUG ("Initialising object");
- gst_osx_audio_sink_create_ringbuffer (GST_BASE_AUDIO_SINK (sink));
+ sink->device_id = kAudioDeviceUnknown;
+ sink->stream_id = kAudioStreamUnknown;
}
static void
@@ -203,8 +205,7 @@ gst_osx_audio_sink_set_property (GObject * object, guint prop_id,
switch (prop_id) {
case ARG_DEVICE:
- if (sink->ringbuffer)
- sink->ringbuffer->device_id = g_value_get_int (value);
+ sink->device_id = g_value_get_int (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -217,14 +218,9 @@ gst_osx_audio_sink_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec)
{
GstOsxAudioSink *sink = GST_OSX_AUDIO_SINK (object);
- int val = 0;
-
switch (prop_id) {
case ARG_DEVICE:
- if (sink->ringbuffer)
- val = sink->ringbuffer->device_id;
-
- g_value_set_int (value, val);
+ g_value_set_int (value, sink->device_id);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -238,32 +234,93 @@ gst_osx_audio_sink_get_property (GObject * object, guint prop_id,
static GstCaps *
gst_osx_audio_sink_getcaps (GstBaseSink * sink)
{
- GstCaps *caps;
+ GstCaps *caps = NULL;
GstOsxAudioSink *osxsink;
OSStatus status;
- AudioValueRange rates[10];
+ AudioValueRange *rates = NULL;
UInt32 propertySize;
int i;
+ gboolean foundFixedRate = FALSE;
+ GstStructure *structure;
+ GValue rate_v = { 0 };
+ GValue rates_v = { 0 };
- propertySize = sizeof (AudioValueRange) * 9;
osxsink = GST_OSX_AUDIO_SINK (sink);
- caps = gst_caps_copy (gst_pad_get_pad_template_caps (GST_BASE_SINK_PAD
- (sink)));
+ gst_osx_audio_sink_select_device (osxsink);
+
+ GST_DEBUG_OBJECT (osxsink, "Using device_id %d", (int) osxsink->device_id);
+
+ status = AudioDeviceGetPropertyInfo (osxsink->device_id, 0, /* Master channel */
+ FALSE, /* isInput */
+ kAudioDevicePropertyAvailableNominalSampleRates, &propertySize, NULL);
+
+ if (status) {
+ GST_WARNING_OBJECT (osxsink, "Failed to get sample rates size: %ld",
+ status);
+ goto done;
+ }
+ GST_DEBUG_OBJECT (osxsink, "Allocating %d bytes for sizes",
+ (int) propertySize);
+ rates = g_malloc (propertySize);
- status = AudioDeviceGetProperty (osxsink->ringbuffer->device_id, 0, FALSE,
- kAudioDevicePropertyAvailableNominalSampleRates, &propertySize, &rates);
+ status = AudioDeviceGetProperty (osxsink->device_id, 0, /* Master channel */
+ FALSE, /* isInput */
+ kAudioDevicePropertyAvailableNominalSampleRates, &propertySize, rates);
+
+ if (status) {
+ GST_WARNING_OBJECT (osxsink, "Failed to get sample rates: %ld", status);
+ goto done;
+ }
+
+ GST_DEBUG_OBJECT (osxsink, "Used %d bytes for sizes", (int) propertySize);
+
+ if (propertySize < sizeof (AudioValueRange)) {
+ GST_WARNING_OBJECT (osxsink, "Zero sample rates available");
+ goto done;
+ }
+
+ /* Create base caps object, then modify to suit. */
+ caps = gst_caps_copy (gst_pad_get_pad_template_caps (GST_BASE_SINK_PAD
+ (sink)));
+ structure = gst_caps_get_structure (caps, 0);
GST_DEBUG
("Getting available sample rates: Status: %ld number of ranges: %lu",
status, propertySize / sizeof (AudioValueRange));
+ g_value_init (&rates_v, GST_TYPE_LIST);
+ g_value_init (&rate_v, G_TYPE_INT);
+
for (i = 0; i < propertySize / sizeof (AudioValueRange); i++) {
GST_LOG_OBJECT (osxsink, "Range from %f to %f", rates[i].mMinimum,
rates[i].mMaximum);
+ if (rates[i].mMinimum == rates[i].mMaximum) {
+ /* For now, we only support these in this form. If there are none
+ * in this form, we use the first (only) as a range. */
+ foundFixedRate = TRUE;
+
+ g_value_set_int (&rate_v, rates[i].mMinimum);
+ gst_value_list_append_value (&rates_v, &rate_v);
+ }
}
+ g_value_unset (&rate_v);
+
+ if (foundFixedRate) {
+ gst_structure_set_value (structure, "rate", &rates_v);
+ } else {
+ gst_structure_set (structure, "rate", GST_TYPE_INT_RANGE,
+ rates[0].mMinimum, rates[0].mMaximum, NULL);
+ }
+
+ g_value_unset (&rates_v);
+
+done:
+ if (rates)
+ g_free (rates);
+
return caps;
}
@@ -272,19 +329,22 @@ static GstRingBuffer *
gst_osx_audio_sink_create_ringbuffer (GstBaseAudioSink * sink)
{
GstOsxAudioSink *osxsink;
+ GstOsxRingBuffer *ringbuffer;
osxsink = GST_OSX_AUDIO_SINK (sink);
- if (!osxsink->ringbuffer) {
- GST_DEBUG ("Creating ringbuffer");
- osxsink->ringbuffer = g_object_new (GST_TYPE_OSX_RING_BUFFER, NULL);
- GST_DEBUG ("osx sink 0x%p element 0x%p ioproc 0x%p", osxsink,
- GST_OSX_AUDIO_ELEMENT_GET_INTERFACE (osxsink),
- (void *) gst_osx_audio_sink_io_proc);
- osxsink->ringbuffer->element =
- GST_OSX_AUDIO_ELEMENT_GET_INTERFACE (osxsink);
- }
- return GST_RING_BUFFER (osxsink->ringbuffer);
+ gst_osx_audio_sink_select_device (osxsink);
+
+ GST_DEBUG ("Creating ringbuffer");
+ ringbuffer = g_object_new (GST_TYPE_OSX_RING_BUFFER, NULL);
+ GST_DEBUG ("osx sink 0x%p element 0x%p ioproc 0x%p", osxsink,
+ GST_OSX_AUDIO_ELEMENT_GET_INTERFACE (osxsink),
+ (void *) gst_osx_audio_sink_io_proc);
+ ringbuffer->element = GST_OSX_AUDIO_ELEMENT_GET_INTERFACE (osxsink);
+ ringbuffer->device_id = osxsink->device_id;
+ ringbuffer->stream_id = osxsink->stream_id;
+
+ return GST_RING_BUFFER (ringbuffer);
}
OSStatus
@@ -321,31 +381,73 @@ gst_osx_audio_sink_osxelement_init (gpointer g_iface, gpointer iface_data)
iface->io_proc = gst_osx_audio_sink_io_proc;
}
-/* entry point to initialize the plug-in
- * initialize the plug-in itself
- * register the element factories and pad templates
- * register the features
- *
- * exchange the string 'plugin' with your elemnt name
- */
-static gboolean
-plugin_init (GstPlugin * plugin)
+
+static void
+gst_osx_audio_sink_select_device (GstOsxAudioSink * osxsink)
{
- gboolean ret;
+ OSStatus status;
+ UInt32 propertySize;
- ret = gst_element_register (plugin, "osxaudiosink",
- GST_RANK_PRIMARY, GST_TYPE_OSX_AUDIO_SINK);
- return ret && gst_element_register (plugin, "osxaudiosrc",
- GST_RANK_PRIMARY, GST_TYPE_OSX_AUDIO_SRC);
-}
+ if (osxsink->device_id == kAudioDeviceUnknown) {
+ GST_DEBUG_OBJECT (osxsink, "Selecting device for OSXAudioSink");
+ propertySize = sizeof (osxsink->device_id);
+ status =
+ AudioHardwareGetProperty (kAudioHardwarePropertyDefaultOutputDevice,
+ &propertySize, &osxsink->device_id);
+
+ if (status)
+ GST_WARNING_OBJECT (osxsink,
+ "AudioHardwareGetProperty returned %d", (int) status);
+ else
+ GST_DEBUG_OBJECT (osxsink, "AudioHardwareGetProperty returned 0");
+
+ if (osxsink->device_id == kAudioDeviceUnknown)
+ GST_WARNING_OBJECT (osxsink,
+ "AudioHardwareGetProperty: device_id is kAudioDeviceUnknown");
+
+ GST_DEBUG_OBJECT (osxsink, "AudioHardwareGetProperty: device_id is %lu",
+ (long) osxsink->device_id);
+ }
-/* this is the structure that gstreamer looks for to register plugins
- *
- * exchange the strings 'plugin' and 'Template plugin' with you plugin name and
- * description
- */
-GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
- GST_VERSION_MINOR,
- "osxaudio",
- "OSX Audio plugin",
- plugin_init, VERSION, "LGPL", "GStreamer", "http://gstreamer.net/")
+ if (osxsink->stream_id == kAudioStreamUnknown) {
+ AudioStreamID *streams;
+
+ GST_DEBUG_OBJECT (osxsink, "Getting streamid");
+ status = AudioDeviceGetPropertyInfo (osxsink->device_id, 0, /* Master channel */
+ FALSE, /* isInput */
+ kAudioDevicePropertyStreams, &propertySize, NULL);
+
+ if (status) {
+ GST_WARNING_OBJECT (osxsink,
+ "AudioDeviceGetProperty returned %d", (int) status);
+ return;
+ }
+
+ GST_DEBUG_OBJECT (osxsink,
+ "Getting available streamids from %d (%d bytes)",
+ (int) (propertySize / sizeof (AudioStreamID)), propertySize);
+ streams = g_malloc (propertySize);
+ status = AudioDeviceGetProperty (osxsink->device_id, 0, /* Master channel */
+ FALSE, /* isInput */
+ kAudioDevicePropertyStreams, &propertySize, streams);
+
+ if (status) {
+ GST_WARNING_OBJECT (osxsink,
+ "AudioDeviceGetProperty returned %d", (int) status);
+ g_free (streams);
+ return;
+ }
+
+ GST_DEBUG_OBJECT (osxsink, "Getting streamid from %d (%d bytes)",
+ (int) (propertySize / sizeof (AudioStreamID)), propertySize);
+
+ if (propertySize >= sizeof (AudioStreamID)) {
+ osxsink->stream_id = streams[0];
+ GST_DEBUG_OBJECT (osxsink, "Selected stream %d of %d: %d", 0,
+ (int) (propertySize / sizeof (AudioStreamID)),
+ (int) osxsink->stream_id);
+ }
+
+ g_free (streams);
+ }
+}
diff --git a/sys/osxaudio/gstosxaudiosink.h b/sys/osxaudio/gstosxaudiosink.h
index ba71c11d..a46d2448 100644
--- a/sys/osxaudio/gstosxaudiosink.h
+++ b/sys/osxaudio/gstosxaudiosink.h
@@ -71,7 +71,8 @@ struct _GstOsxAudioSink
{
GstBaseAudioSink sink;
- GstOsxRingBuffer *ringbuffer;
+ AudioDeviceID device_id;
+ AudioStreamID stream_id;
};
struct _GstOsxAudioSinkClass
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);
+ }
+}
diff --git a/sys/osxaudio/gstosxaudiosrc.h b/sys/osxaudio/gstosxaudiosrc.h
index 93fc659f..7336c82f 100644
--- a/sys/osxaudio/gstosxaudiosrc.h
+++ b/sys/osxaudio/gstosxaudiosrc.h
@@ -65,7 +65,8 @@ struct _GstOsxAudioSrc
{
GstBaseAudioSrc src;
- GstOsxRingBuffer *ringbuffer;
+ AudioDeviceID device_id;
+ AudioStreamID stream_id;
};
struct _GstOsxAudioSrcClass
diff --git a/sys/osxaudio/gstosxringbuffer.c b/sys/osxaudio/gstosxringbuffer.c
index 428c3806..11689381 100644
--- a/sys/osxaudio/gstosxringbuffer.c
+++ b/sys/osxaudio/gstosxringbuffer.c
@@ -137,37 +137,7 @@ static void
gst_osx_ring_buffer_init (GstOsxRingBuffer * ringbuffer,
GstOsxRingBufferClass * g_class)
{
- OSStatus status;
- UInt32 propertySize;
-
- /* currently do bugger all */
- GST_DEBUG ("osx ring buffer init");
- propertySize = sizeof (ringbuffer->device_id);
- status =
- AudioHardwareGetProperty (kAudioHardwarePropertyDefaultOutputDevice,
- &propertySize, &(ringbuffer->device_id));
- GST_DEBUG ("osx ring buffer called AudioHardwareGetProperty");
- if (status) {
- GST_WARNING ("AudioHardwareGetProperty returned %d", (int) status);
- } else {
- GST_DEBUG ("AudioHardwareGetProperty returned 0");
- }
- if (ringbuffer->device_id == kAudioDeviceUnknown) {
- GST_DEBUG ("AudioHardwareGetProperty: device_id is kAudioDeviceUnknown");
- }
- GST_DEBUG ("AudioHardwareGetProperty: device_id is %lu",
- ringbuffer->device_id);
- /* get requested buffer length */
- propertySize = sizeof (ringbuffer->buffer_len);
- status =
- AudioDeviceGetProperty (ringbuffer->device_id, 0, false,
- kAudioDevicePropertyBufferSize, &propertySize, &ringbuffer->buffer_len);
- if (status) {
- GST_WARNING
- ("AudioDeviceGetProperty returned %d when getting kAudioDevicePropertyBufferSize",
- (int) status);
- }
- GST_DEBUG ("%5d ringbuffer->buffer_len", (int) ringbuffer->buffer_len);
+ /* Nothing to do right now */
}
static void
@@ -199,15 +169,65 @@ gst_osx_ring_buffer_close_device (GstRingBuffer * buf)
static gboolean
gst_osx_ring_buffer_acquire (GstRingBuffer * buf, GstRingBufferSpec * spec)
{
- /* stub, we need to allocate ringbuffer memory */
+ /* Configure the output stream and allocate ringbuffer memory */
GstOsxRingBuffer *osxbuf;
+ AudioStreamBasicDescription asbd;
+ AudioStreamBasicDescription asbd2;
+ OSStatus status;
+ UInt32 buffer_len;
+ UInt32 propertySize;
osxbuf = GST_OSX_RING_BUFFER (buf);
- spec->segsize = osxbuf->buffer_len;
+ /* Fill out the audio description we're going to be using */
+ asbd.mFormatID = kAudioFormatLinearPCM;
+ asbd.mSampleRate = (double) spec->rate;
+ asbd.mChannelsPerFrame = spec->channels;
+ asbd.mFormatFlags = kAudioFormatFlagsNativeFloatPacked;
+ asbd.mBytesPerFrame = spec->channels * sizeof (float);
+ asbd.mBitsPerChannel = sizeof (float) * 8;
+ asbd.mBytesPerPacket = spec->channels * sizeof (float);
+ asbd.mFramesPerPacket = 1;
+ asbd.mReserved = 0;
+
+ GST_LOG_OBJECT (osxbuf, "Format: %x, %f, %d, %x, %d, %d, %d, %d, %d",
+ asbd.mFormatID,
+ asbd.mSampleRate,
+ asbd.mChannelsPerFrame,
+ asbd.mFormatFlags,
+ asbd.mBytesPerFrame,
+ asbd.mBitsPerChannel,
+ asbd.mBytesPerPacket, asbd.mFramesPerPacket, asbd.mReserved);
+
+ GST_DEBUG_OBJECT (osxbuf, "Using stream_id %d, setting output format",
+ (int) osxbuf->stream_id);
+
+ propertySize = sizeof (asbd);
+ status = AudioStreamSetProperty (osxbuf->stream_id, NULL, /* Change immediately */
+ 0, /* Master channel */
+ kAudioStreamPropertyVirtualFormat, propertySize, &asbd);
+
+ if (status) {
+ GST_WARNING_OBJECT (osxbuf, "Failed to set output description: %lx",
+ status);
+ return FALSE;
+ }
+
+ /* get requested buffer length to use */
+ propertySize = sizeof (buffer_len);
+ status = AudioDeviceGetProperty (osxbuf->device_id, 0, false, /* TODO, this should be true for the source element */
+ kAudioDevicePropertyBufferSize, &propertySize, &buffer_len);
+
+ if (status) {
+ GST_WARNING_OBJECT (osxbuf,
+ "AudioDeviceGetProperty returned %d when getting "
+ "kAudioDevicePropertyBufferSize", (int) status);
+ }
+ GST_DEBUG_OBJECT (osxbuf, "%5d osxbuf->buffer_len", (int) buffer_len);
+ spec->segsize = buffer_len;
spec->segtotal = 16;
- GST_DEBUG ("osx ring buffer acquire");
+ GST_DEBUG_OBJECT (osxbuf, "osx ring buffer acquired");
buf->data = gst_buffer_new_and_alloc (spec->segtotal * spec->segsize);
memset (GST_BUFFER_DATA (buf->data), 0, GST_BUFFER_SIZE (buf->data));
diff --git a/sys/osxaudio/gstosxringbuffer.h b/sys/osxaudio/gstosxringbuffer.h
index bc8d5524..40a299ff 100644
--- a/sys/osxaudio/gstosxringbuffer.h
+++ b/sys/osxaudio/gstosxringbuffer.h
@@ -67,6 +67,7 @@ struct _GstOsxRingBuffer {
GstRingBuffer object;
AudioDeviceID device_id;
+ AudioStreamID stream_id;
gboolean io_proc_active;
guint buffer_len;
GstOsxAudioElementInterface* element;