summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog16
-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
9 files changed, 340 insertions, 136 deletions
diff --git a/ChangeLog b/ChangeLog
index 75c7634d..faaa4f1e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2008-08-26 Michael Smith <msmith@songbirdnest.com>
+
+ * 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.
+
2008-08-26 Stefan Kost <ensonic@users.sf.net>
* sys/v4l2/gstv4l2object.c:
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;