diff options
author | Zaheer Abbas Merali <zaheerabbas@merali.org> | 2006-04-26 16:29:38 +0000 |
---|---|---|
committer | Zaheer Abbas Merali <zaheerabbas@merali.org> | 2006-04-26 16:29:38 +0000 |
commit | cb163be477869c77651ccf659080bb74ca595e04 (patch) | |
tree | 1df0c0840e902ecce1183b62e425d9c0a33279c6 /sys/osxaudio/gstosxaudioelement.c | |
parent | a3fca5680bd81ce8880be7fba1d8a8c7955d5f4e (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.c | 455 |
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; } |