summaryrefslogtreecommitdiffstats
path: root/sys/osxaudio/gstosxaudioelement.c
diff options
context:
space:
mode:
authorZaheer Abbas Merali <zaheerabbas@merali.org>2006-04-26 16:29:38 +0000
committerZaheer Abbas Merali <zaheerabbas@merali.org>2006-04-26 16:29:38 +0000
commitcb163be477869c77651ccf659080bb74ca595e04 (patch)
tree1df0c0840e902ecce1183b62e425d9c0a33279c6 /sys/osxaudio/gstosxaudioelement.c
parenta3fca5680bd81ce8880be7fba1d8a8c7955d5f4e (diff)
sys/osxaudio/: Port of osxaudiosink to 0.10
Original commit message from CVS: 2006-04-26 Zaheer Abbas Merali <zaheerabbas at merali dot org> * sys/osxaudio/Makefile.am: * sys/osxaudio/gstosxaudioelement.c: (gst_osx_audio_element_get_type), (gst_osx_audio_element_class_init): * sys/osxaudio/gstosxaudioelement.h: * sys/osxaudio/gstosxaudiosink.c: (gst_osx_audio_sink_osxelement_do_init), (gst_osx_audio_sink_base_init), (gst_osx_audio_sink_class_init), (gst_osx_audio_sink_init), (gst_osx_audio_sink_set_property), (gst_osx_audio_sink_get_property), (gst_osx_audio_sink_getcaps), (gst_osx_audio_sink_create_ringbuffer), (gst_osx_audio_sink_io_proc), (gst_osx_audio_sink_osxelement_init), (plugin_init): * sys/osxaudio/gstosxaudiosink.h: Port of osxaudiosink to 0.10
Diffstat (limited to 'sys/osxaudio/gstosxaudioelement.c')
-rw-r--r--sys/osxaudio/gstosxaudioelement.c455
1 files changed, 48 insertions, 407 deletions
diff --git a/sys/osxaudio/gstosxaudioelement.c b/sys/osxaudio/gstosxaudioelement.c
index 6e1d7917..2ba44456 100644
--- a/sys/osxaudio/gstosxaudioelement.c
+++ b/sys/osxaudio/gstosxaudioelement.c
@@ -1,8 +1,29 @@
-/* GStreamer
- * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
- * 2000 Wim Taymans <wim.taymans@chello.be>
+/*
+ * GStreamer
+ * Copyright 2006 Zaheer Abbas Merali <zaheerabbas at merali dot org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
*
- * gstosxaudioelement.c:
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Alternatively, the contents of this file may be used under the
+ * GNU Lesser General Public License Version 2.1 (the "LGPL"), in
+ * which case the following provisions apply instead of the ones
+ * mentioned above:
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -20,430 +41,50 @@
* Boston, MA 02111-1307, USA.
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <CoreAudio/CoreAudio.h>
-#include <pthread.h>
-
-#include <unistd.h>
-#include <errno.h>
-#include <string.h>
-
+#include <gst/gst.h>
#include "gstosxaudioelement.h"
-enum
-{
- ARG_0,
- ARG_DEVICE
-};
-
-/* elementfactory information */
-static const GstElementDetails gst_osxaudioelement_details =
-GST_ELEMENT_DETAILS ("Audio Mixer (OSX)",
- "Generic/Audio",
- "Mac OS X audio mixer element",
- "Zaheer Abbas Merali <zaheerabbas at merali dot org>");
-
-static void gst_osxaudioelement_base_init (GstOsxAudioElementClass * klass);
-static void gst_osxaudioelement_class_init (GstOsxAudioElementClass * klass);
-
-static void gst_osxaudioelement_init (GstOsxAudioElement * osxaudio);
-static void gst_osxaudioelement_dispose (GObject * object);
-
-static void gst_osxaudioelement_set_property (GObject * object,
- guint prop_id, const GValue * value, GParamSpec * pspec);
-static void gst_osxaudioelement_get_property (GObject * object,
- guint prop_id, GValue * value, GParamSpec * pspec);
-static GstStateChangeReturn gst_osxaudioelement_change_state (GstElement *
- element);
-
-static GstElementClass *parent_class = NULL;
-
+static void
+gst_osx_audio_element_class_init (GstOsxAudioElementInterface * klass);
GType
-gst_osxaudioelement_get_type (void)
+gst_osx_audio_element_get_type ()
{
- static GType osxaudioelement_type = 0;
+ static GType gst_osxaudioelement_type = 0;
- if (!osxaudioelement_type) {
- static const GTypeInfo osxaudioelement_info = {
- sizeof (GstOsxAudioElementClass),
- (GBaseInitFunc) gst_osxaudioelement_base_init,
+ if (!gst_osxaudioelement_type) {
+ static const GTypeInfo gst_osxaudioelement_info = {
+ sizeof (GstOsxAudioElementInterface),
+ (GBaseInitFunc) gst_osx_audio_element_class_init,
+ NULL,
NULL,
- (GClassInitFunc) gst_osxaudioelement_class_init,
NULL,
NULL,
- sizeof (GstOsxAudioElement),
0,
- (GInstanceInitFunc) gst_osxaudioelement_init
+ 0,
+ NULL,
};
- osxaudioelement_type = g_type_register_static (GST_TYPE_ELEMENT,
- "GstOsxAudioElement", &osxaudioelement_info, 0);
- }
-
- return osxaudioelement_type;
-}
-
-static void
-gst_osxaudioelement_base_init (GstOsxAudioElementClass * klass)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
-
- klass->device_combinations = NULL;
-
- gst_element_class_set_details (element_class, &gst_osxaudioelement_details);
-}
-
-static void
-gst_osxaudioelement_class_init (GstOsxAudioElementClass * klass)
-{
- GObjectClass *gobject_class;
- GstElementClass *gstelement_class;
-
- gobject_class = (GObjectClass *) klass;
- gstelement_class = (GstElementClass *) klass;
-
- parent_class = g_type_class_peek_parent (klass);
-
- g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DEVICE,
- g_param_spec_int ("device", "Device index",
- "Mac OS X CoreAudio Device Index (0 usually)", 0, G_MAXINT, 0,
- G_PARAM_READWRITE));
- gobject_class->set_property = gst_osxaudioelement_set_property;
- gobject_class->get_property = gst_osxaudioelement_get_property;
- gobject_class->dispose = gst_osxaudioelement_dispose;
-
- gstelement_class->change_state = gst_osxaudioelement_change_state;
-}
-
-static void
-gst_osxaudioelement_init (GstOsxAudioElement * osxaudio)
-{
- OSStatus status;
- UInt32 propertySize;
-
- pthread_mutex_init (&osxaudio->buffer_mutex, NULL);
- pthread_mutex_unlock (&osxaudio->buffer_mutex);
- propertySize = sizeof (osxaudio->device_id);
- status =
- AudioHardwareGetProperty (kAudioHardwarePropertyDefaultOutputDevice,
- &propertySize, &(osxaudio->device_id));
-
- if (status) {
- GST_DEBUG ("AudioHardwareGetProperty returned %d\n", (int) status);
- }
- if (osxaudio->device_id == kAudioDeviceUnknown) {
- GST_DEBUG ("AudioHardwareGetProperty: device_id is kAudioDeviceUnknown\n");
- }
- /* get requested buffer length */
- propertySize = sizeof (osxaudio->buffer_len);
- status =
- AudioDeviceGetProperty (osxaudio->device_id, 0, false,
- kAudioDevicePropertyBufferSize, &propertySize, &osxaudio->buffer_len);
- if (status) {
- GST_DEBUG
- ("AudioDeviceGetProperty returned %d when getting kAudioDevicePropertyBufferSize\n",
- (int) status);
- }
- GST_DEBUG ("%5d osxaudio->buffer_len\n", (int) osxaudio->buffer_len);
-
-}
-
-static void
-gst_osxaudioelement_dispose (GObject * object)
-{
- /* GstOsxAudioElement *osxaudio = (GstOsxAudioElement *) object; */
-
- G_OBJECT_CLASS (parent_class)->dispose (object);
-}
-
-/* General purpose Ring-buffering routines */
-int
-write_buffer (GstOsxAudioElement * osxaudio, unsigned char *data, int len)
-{
- int len2 = 0;
- int x;
-
- while (len > 0) {
- if (osxaudio->full_buffers == NUM_BUFS) {
- GST_DEBUG ("Buffer overrun\n");
- break;
- }
-
- x = osxaudio->buffer_len - osxaudio->buf_write_pos;
- if (x > len)
- x = len;
- memcpy (osxaudio->buffer[osxaudio->buf_write] + osxaudio->buf_write_pos,
- data + len2, x);
-
- /* accessing common variables, locking mutex */
- pthread_mutex_lock (&osxaudio->buffer_mutex);
- len2 += x;
- len -= x;
- osxaudio->buffered_bytes += x;
- osxaudio->buf_write_pos += x;
- if (osxaudio->buf_write_pos >= osxaudio->buffer_len) {
- /* block is full, find next! */
- osxaudio->buf_write = (osxaudio->buf_write + 1) % NUM_BUFS;
- ++osxaudio->full_buffers;
- osxaudio->buf_write_pos = 0;
- }
- pthread_mutex_unlock (&osxaudio->buffer_mutex);
- }
-
- return len2;
-}
-
-int
-read_buffer (GstOsxAudioElement * osxaudio, unsigned char *data)
-{
- int len2 = 0;
- int len = osxaudio->buffer_len;
- int x;
-
- while (len > 0) {
- if (osxaudio->full_buffers == 0) {
- GST_DEBUG ("Buffer underrun\n");
- break;
- }
-
- x = osxaudio->buffer_len - osxaudio->buf_read_pos;
- if (x > len)
- x = len;
- memcpy (data + len2,
- osxaudio->buffer[osxaudio->buf_read] + osxaudio->buf_read_pos, x);
- len2 += x;
- len -= x;
-
- /* accessing common variables, locking mutex */
- pthread_mutex_lock (&osxaudio->buffer_mutex);
- osxaudio->buffered_bytes -= x;
- osxaudio->buf_read_pos += x;
- if (osxaudio->buf_read_pos >= osxaudio->buffer_len) {
- /* block is empty, find next! */
- osxaudio->buf_read = (osxaudio->buf_read + 1) % NUM_BUFS;
- --osxaudio->full_buffers;
- osxaudio->buf_read_pos = 0;
- }
- pthread_mutex_unlock (&osxaudio->buffer_mutex);
- }
-
-
- return len2;
-}
-
-/* The function that the CoreAudio thread calls when it has data */
-OSStatus
-inputAudioDeviceIOProc (AudioDeviceID inDevice, const AudioTimeStamp * inNow,
- const AudioBufferList * inInputData, const AudioTimeStamp * inInputTime,
- AudioBufferList * outOutputData, const AudioTimeStamp * inOutputTime,
- void *inClientData)
-{
- GstOsxAudioElement *osxaudio = GST_OSXAUDIOELEMENT (inClientData);
-
- write_buffer (GST_OSXAUDIOELEMENT (osxaudio),
- (char *) inInputData->mBuffers[0].mData, osxaudio->buffer_len);
-
- return 0;
-}
-
-/* The function that the CoreAudio thread calls when it wants more data */
-
-OSStatus
-outputAudioDeviceIOProc (AudioDeviceID inDevice, const AudioTimeStamp * inNow,
- const AudioBufferList * inInputData, const AudioTimeStamp * inInputTime,
- AudioBufferList * outOutputData, const AudioTimeStamp * inOutputTime,
- void *inClientData)
-{
- GstOsxAudioElement *osxaudio = GST_OSXAUDIOELEMENT (inClientData);
-
- outOutputData->mBuffers[0].mDataByteSize =
- read_buffer (osxaudio, (char *) outOutputData->mBuffers[0].mData);
-
- return 0;
-}
-
-static gboolean
-gst_osxaudioelement_open_audio (GstOsxAudioElement * osxaudio, gboolean input)
-{
- int i;
- OSErr status;
-
- GST_INFO ("osxaudioelement: attempting to open sound device");
-
- /* Allocate ring-buffer memory */
- for (i = 0; i < NUM_BUFS; i++)
- osxaudio->buffer[i] = (unsigned char *) malloc (osxaudio->buffer_len);
- if (input) {
- status =
- AudioDeviceAddIOProc (osxaudio->device_id, inputAudioDeviceIOProc,
- osxaudio);
- } else {
- /* Set the IO proc that CoreAudio will call when it needs data */
- status =
- AudioDeviceAddIOProc (osxaudio->device_id, outputAudioDeviceIOProc,
- osxaudio);
- }
- if (status) {
- GST_DEBUG ("AudioDeviceAddIOProc returned %d\n", (int) status);
- return FALSE;
- }
-
- pthread_mutex_lock (&osxaudio->buffer_mutex);
-
- /* reset ring-buffer state */
- osxaudio->buf_read = 0;
- osxaudio->buf_write = 0;
- osxaudio->buf_read_pos = 0;
- osxaudio->buf_write_pos = 0;
-
- osxaudio->full_buffers = 0;
- osxaudio->buffered_bytes = 0;
-
- /* zero buffer */
- for (i = 0; i < NUM_BUFS; i++)
- bzero (osxaudio->buffer[i], osxaudio->buffer_len);
-
- pthread_mutex_unlock (&osxaudio->buffer_mutex);
-
- return TRUE;
-}
-
-static void
-gst_osxaudioelement_close_audio (GstOsxAudioElement * osxaudio, gboolean input)
-{
- OSErr status;
- int i;
-
- /* stop callback */
- if (input) {
- status = AudioDeviceStop (osxaudio->device_id, inputAudioDeviceIOProc);
- } else {
- status = AudioDeviceStop (osxaudio->device_id, outputAudioDeviceIOProc);
- }
- if (status)
- GST_DEBUG ("AudioDeviceStop returned %d\n", (int) status);
-
- if (input) {
- status =
- AudioDeviceRemoveIOProc (osxaudio->device_id, inputAudioDeviceIOProc);
- } else {
- status =
- AudioDeviceRemoveIOProc (osxaudio->device_id, outputAudioDeviceIOProc);
+ gst_osxaudioelement_type = g_type_register_static (G_TYPE_INTERFACE,
+ "GstOsxAudioElement", &gst_osxaudioelement_info, 0);
+ /*g_type_interface_add_prerequisite (gst_osxaudioelement_type,
+ GST_TYPE_IMPLEMENTS_INTERFACE); */
}
- if (status)
- GST_DEBUG ("AudioDeviceRemoveIOProc " "returned %d\n", (int) status);
-
- for (i = 0; i < NUM_BUFS; i++)
- free (osxaudio->buffer[i]);
+ return gst_osxaudioelement_type;
}
static void
-gst_osxaudioelement_set_property (GObject * object,
- guint prop_id, const GValue * value, GParamSpec * pspec)
+gst_osx_audio_element_class_init (GstOsxAudioElementInterface * klass)
{
- GstOsxAudioElement *osxaudio = GST_OSXAUDIOELEMENT (object);
- OSStatus status;
- int nDevices;
- UInt32 propertySize;
- int deviceid;
- AudioDeviceID *devids;
+ static gboolean initialized = FALSE;
- switch (prop_id) {
- case ARG_DEVICE:
- /* check index given is in bounds, if not use default device */
- status = AudioHardwareGetPropertyInfo (kAudioHardwarePropertyDevices,
- &propertySize, NULL);
- nDevices = propertySize / sizeof (AudioDeviceID);
- deviceid = g_value_get_int (value);
- if (deviceid < nDevices) {
- devids = malloc (propertySize);
- status =
- AudioHardwareGetProperty (kAudioHardwarePropertyDevices,
- &propertySize, devids);
- osxaudio->device_id = devids[deviceid];
- free (devids);
- } else {
- GST_DEBUG ("device index %d out of range. Max index is currently %d\n",
- deviceid, nDevices);
- }
- break;
- default:
- break;
- }
-}
+ if (!initialized) {
-static void
-gst_osxaudioelement_get_property (GObject * object,
- guint prop_id, GValue * value, GParamSpec * pspec)
-{
- GstOsxAudioElement *osxaudio = GST_OSXAUDIOELEMENT (object);
- OSStatus status;
- int nDevices;
- UInt32 propertySize;
- AudioDeviceID *devids;
- int i;
-
- switch (prop_id) {
- case ARG_DEVICE:
- /* figure out what index the current one is */
- status = AudioHardwareGetPropertyInfo (kAudioHardwarePropertyDevices,
- &propertySize, NULL);
- nDevices = propertySize / sizeof (AudioDeviceID);
- devids = malloc (propertySize);
- status =
- AudioHardwareGetProperty (kAudioHardwarePropertyDevices,
- &propertySize, devids);
- for (i = 0; i < nDevices; i++) {
- if (osxaudio->device_id == devids[i])
- break;
- }
- g_value_set_int (value, i);
- free (devids);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static GstStateChangeReturn
-gst_osxaudioelement_change_state (GstElement * element,
- GstStateChange transition)
-{
- GstOsxAudioElement *osxaudio = GST_OSXAUDIOELEMENT (element);
- const GList *padlist;
- gboolean input = TRUE;
-
- padlist = gst_element_get_pad_list (element);
- if (padlist != NULL) {
- GstPad *firstpad = padlist->data;
-
- if (GST_PAD_IS_SINK (firstpad)) {
- input = FALSE;
- }
- }
- switch (transition) {
- case GST_STATE_CHANGE_NULL_TO_READY:
- if (!gst_osxaudioelement_open_audio (osxaudio, input)) {
- return GST_STATE_CHANGE_FAILURE;
- }
- GST_INFO ("osxaudioelement: opened sound device");
- break;
- case GST_STATE_CHANGE_READY_TO_NULL:
- gst_osxaudioelement_close_audio (osxaudio, input);
- GST_INFO ("osxaudioelement: closed sound device");
- break;
- default:
- break;
+ initialized = TRUE;
}
- if (GST_ELEMENT_CLASS (parent_class)->change_state)
- return GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
+ /* default virtual functions */
+ klass->io_proc = NULL;
- return GST_STATE_CHANGE_SUCCESS;
}