Bug 459765 - Update to libsydneyaudio r3730 r=kinetik
authorChris Double <chris.double@double.co.nz>
Thu, 16 Oct 2008 16:16:29 +1300
changeset 20529 e26faadf2c8409b2e625b737ee6e80bb201fe997
parent 20528 f253090ba770bb21b2fc61921ad02e51fe1c24bc
child 20530 5a5fa534d63ed3f144c163eaa3eff28bf966084c
push idunknown
push userunknown
push dateunknown
reviewerskinetik
bugs459765
milestone1.9.1b2pre
Bug 459765 - Update to libsydneyaudio r3730 r=kinetik
content/media/video/src/nsAudioStream.cpp
layout/build/Makefile.in
media/liboggplay_audio/Makefile.in
media/liboggplay_audio/README_MOZILLA
media/liboggplay_audio/sydney_audio.h
media/liboggplay_audio/sydney_audio_alsa.c
media/liboggplay_audio/sydney_audio_mac.c
media/liboggplay_audio/sydney_audio_oss.c
media/liboggplay_audio/sydney_audio_waveapi.c
media/liboggplay_audio/update.sh
media/libsydneyaudio/AUTHORS
media/libsydneyaudio/Makefile.in
media/libsydneyaudio/README_MOZILLA
media/libsydneyaudio/include/Makefile.in
media/libsydneyaudio/include/sydney_audio.h
media/libsydneyaudio/src/Makefile.in
media/libsydneyaudio/src/sydney_audio_alsa.c
media/libsydneyaudio/src/sydney_audio_mac.c
media/libsydneyaudio/src/sydney_audio_oss.c
media/libsydneyaudio/src/sydney_audio_pulseaudio.c
media/libsydneyaudio/src/sydney_audio_sunaudio.c
media/libsydneyaudio/src/sydney_audio_waveapi.c
media/libsydneyaudio/update.sh
toolkit/toolkit-makefiles.sh
toolkit/toolkit-tiers.mk
--- a/content/media/video/src/nsAudioStream.cpp
+++ b/content/media/video/src/nsAudioStream.cpp
@@ -37,17 +37,17 @@
  * ***** END LICENSE BLOCK ***** */
 #include <stdio.h>
 #include <math.h>
 #include "prlog.h"
 #include "prmem.h"
 #include "nsAutoPtr.h"
 #include "nsAudioStream.h"
 extern "C" {
-#include "oggplay_audio/sydney_audio.h"
+#include "sydneyaudio/sydney_audio.h"
 }
 
 #ifdef PR_LOGGING
 PRLogModuleInfo* gAudioStreamLog = nsnull;
 #endif
 
 nsresult nsAudioStream::InitLibrary()
 {
--- a/layout/build/Makefile.in
+++ b/layout/build/Makefile.in
@@ -151,17 +151,17 @@ SHARED_LIBRARY_LIBS 	+= \
 endif
 
 ifdef MOZ_OGG
 SHARED_LIBRARY_LIBS 	+= \
 	$(DEPTH)/media/libfishsound/src/libfishsound/$(LIB_PREFIX)fishsound.$(LIB_SUFFIX) \
 	$(DEPTH)/media/libogg/src/$(LIB_PREFIX)ogg.$(LIB_SUFFIX) \
 	$(DEPTH)/media/liboggplay/src/liboggplay/$(LIB_PREFIX)oggplay.$(LIB_SUFFIX) \
 	$(DEPTH)/media/liboggz/src/liboggz/$(LIB_PREFIX)oggz.$(LIB_SUFFIX) \
-	$(DEPTH)/media/liboggplay_audio/$(LIB_PREFIX)oggplay_audio.$(LIB_SUFFIX) \
+	$(DEPTH)/media/libsydneyaudio/src/$(LIB_PREFIX)sydneyaudio.$(LIB_SUFFIX) \
 	$(DEPTH)/media/libtheora/lib/$(LIB_PREFIX)theora.$(LIB_SUFFIX) \
 	$(DEPTH)/media/libvorbis/lib/$(LIB_PREFIX)vorbis.$(LIB_SUFFIX) \
 	$(NULL)
 endif
 
 ifdef NS_PRINTING
 SHARED_LIBRARY_LIBS += \
 		../printing/$(LIB_PREFIX)gkprinting_s.$(LIB_SUFFIX) \
deleted file mode 100644
--- a/media/liboggplay_audio/Makefile.in
+++ /dev/null
@@ -1,79 +0,0 @@
-# ***** BEGIN LICENSE BLOCK *****
-# Version: MPL 1.1/GPL 2.0/LGPL 2.1
-#
-# The contents of this file are subject to the Mozilla Public License Version
-# 1.1 (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-# http://www.mozilla.org/MPL/
-#
-# Software distributed under the License is distributed on an "AS IS" basis,
-# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-# for the specific language governing rights and limitations under the
-# License.
-#
-# The Original Code is Mozilla code.
-#
-# The Initial Developer of the Original Code is the Mozilla Corporation.
-# Portions created by the Initial Developer are Copyright (C) 2007
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-#  Chris Double <chris.double@double.co.nz>
-#
-# Alternatively, the contents of this file may be used under the terms of
-# either the GNU General Public License Version 2 or later (the "GPL"), or
-# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
-# in which case the provisions of the GPL or the LGPL are applicable instead
-# of those above. If you wish to allow use of your version of this file only
-# under the terms of either the GPL or the LGPL, and not to allow others to
-# use your version of this file under the terms of the MPL, indicate your
-# decision by deleting the provisions above and replace them with the notice
-# and other provisions required by the GPL or the LGPL. If you do not delete
-# the provisions above, a recipient may use your version of this file under
-# the terms of any one of the MPL, the GPL or the LGPL.
-#
-# ***** END LICENSE BLOCK *****
-
-DEPTH		= ../..
-topsrcdir	= @top_srcdir@
-srcdir		= @srcdir@
-VPATH		= @srcdir@
-
-include $(DEPTH)/config/autoconf.mk
-
-MODULE		= oggplay_audio
-LIBRARY_NAME	= oggplay_audio
-FORCE_STATIC_LIB= 1
-
-EXPORTS		= \
-		sydney_audio.h \
-		$(NULL)
-
-ifeq ($(OS_ARCH),Linux)
-CSRCS		= \
-		sydney_audio_alsa.c \
-		$(NULL)
-endif
-
-ifneq (,$(filter WINNT WINCE,$(OS_ARCH)))
-CSRCS		= \
-		sydney_audio_waveapi.c \
-		$(NULL)
-endif
-
-ifeq ($(OS_ARCH),Darwin)
-CSRCS		= \
-		sydney_audio_mac.c \
-		$(NULL)
-
-OS_LIBS += -framework CoreAudio -framework AudioToolbox -framework AudioUnit -framework Carbon
-endif
-
-ifeq ($(OS_ARCH),WINNT)
-OS_LIBS += winmm.lib
-endif
-
-include $(topsrcdir)/config/rules.mk
-
-LOCAL_INCLUDES = -I$(srcdir)
-
deleted file mode 100644
--- a/media/liboggplay_audio/README_MOZILLA
+++ /dev/null
@@ -1,11 +0,0 @@
-The liboggplay_audio code is from the audio portion of the Annodex
-browser_plugin svn repository:
-
-http://svn.annodex.net/browser_plugin/trunk/src/audio/
-
-It was originally part of liboggplay but recently split into the
-separate browser_plugin directory. I only use the audio portion so
-only the audio part of the source is here. Run update.sh giving it the
-path to a checked out version of browser_plugin to update this code.
-
-This code is using svn revision r3605 and apply the patch from bug 449564.
deleted file mode 100644
--- a/media/liboggplay_audio/sydney_audio.h
+++ /dev/null
@@ -1,414 +0,0 @@
-#ifndef foosydneyhfoo
-#define foosydneyhfoo
-
-/* Requirements:
-
-- In sync mode, the device will automatically write data so that an initial read causes writes
-of zeros to be issued to that one can do "while (1); {read(); write()}
-
-- All functions are thread-safe and can be called in any thread context. None of the functions is
-async-signal safe.
-  
-- It is assumed that duplex streams have a single clock (synchronised)
-*/
-
-#include <sys/types.h>
-#if !defined (WIN32)
-#include <sys/param.h>
-#include <inttypes.h>
-#else
-#include <stddef.h>
-#endif
-
-/* Detect byte order, based on sys/param.h */
-#undef SA_LITTLE_ENDIAN
-#undef SA_BIG_ENDIAN
-
-#if defined(__BYTE_ORDER)
-#   if __BYTE_ORDER == __LITTLE_ENDIAN
-#       define SA_LITTLE_ENDIAN 1
-#   elif __BYTE_ORDER == __BIG_ENDIAN
-#       define SA_BIG_ENDIAN 1
-#   endif
-#elif defined(WIN32)
-#   define SA_LITTLE_ENDIAN 1
-#elif defined(__APPLE__)
-#   if defined(__BIG_ENDIAN__)
-#       define SA_BIG_ENDIAN 1
-#   else
-#       define SA_LITTLE_ENDIAN 1
-#   endif
-#else
-#    error "Cannot determine byte order!"
-#endif
-
-#if defined(WIN32)
-#if !defined(int32_t)
-typedef __int32 int32_t;
-#endif
-#if !defined(int64_t)
-typedef __int64 int64_t;
-#endif
-#endif
-
-typedef struct sa_stream sa_stream_t;
-
-#if defined(WIN32)
-// (left << 16 | right) (16 bits per channel)
-#define SA_VOLUME_MUTED ((int32_t) (0x00000000))
-#else
-/** Volume that corresponds to muted in/out */
-#define SA_VOLUME_MUTED ((int32_t) (-0x80000000))
-#endif
-
-/** Ways to express seek offsets for pread/pwrite */
-typedef enum {
-    SA_SEEK_RELATIVE,
-    SA_SEEK_ABSOLUTE,
-    SA_SEEK_RELATIVE_END,
-    _SA_SEEK_MAX
-} sa_seek_t;
-
-/** Supported formats */
-typedef enum {
-    SA_PCM_FORMAT_U8,
-    SA_PCM_FORMAT_ULAW,
-    SA_PCM_FORMAT_ALAW,
-    SA_PCM_FORMAT_S16_LE,
-    SA_PCM_FORMAT_S16_BE,
-    SA_PCM_FORMAT_S24_LE,
-    SA_PCM_FORMAT_S24_BE,
-    SA_PCM_FORMAT_S32_LE,
-    SA_PCM_FORMAT_S32_BE,
-    SA_PCM_FORMAT_FLOAT32_LE,
-    SA_PCM_FORMAT_FLOAT32_BE,
-    _SA_PCM_FORMAT_MAX
-} sa_pcm_format_t;
-
-/* Native/reverse endianness definitions for PCM */
-#ifdef SA_LITTLE_ENDIAN
-#define SA_PCM_FORMAT_S16_NE SA_PCM_FORMAT_S16_LE
-#define SA_PCM_FORMAT_S24_NE SA_PCM_FORMAT_S24_LE
-#define SA_PCM_FORMAT_S32_NE SA_PCM_FORMAT_S32_LE
-#define SA_PCM_FORMAT_FLOAT32_NE SA_PCM_FORMAT_FLOAT32_LE
-#define SA_PCM_FORMAT_S16_RE SA_PCM_FORMAT_S16_BE
-#define SA_PCM_FORMAT_S24_RE SA_PCM_FORMAT_S24_BE
-#define SA_PCM_FORMAT_S32_RE SA_PCM_FORMAT_S32_BE
-#define SA_PCM_FORMAT_FLOAT32_RE SA_PCM_FORMAT_FLOAT32_BE
-#else
-#define SA_PCM_FORMAT_S16_NE SA_PCM_FORMAT_S16_BE
-#define SA_PCM_FORMAT_S24_NE SA_PCM_FORMAT_S24_BE
-#define SA_PCM_FORMAT_S32_NE SA_PCM_FORMAT_S32_BE
-#define SA_PCM_FORMAT_FLOAT32_NE SA_PCM_FORMAT_FLOAT32_BE
-#define SA_PCM_FORMAT_S16_RE SA_PCM_FORMAT_S16_LE
-#define SA_PCM_FORMAT_S24_RE SA_PCM_FORMAT_S24_LE
-#define SA_PCM_FORMAT_S32_RE SA_PCM_FORMAT_S32_LE
-#define SA_PCM_FORMAT_FLOAT32_RE SA_PCM_FORMAT_FLOAT32_LE
-#endif
-
-#define SA_CODEC_MPEG "mpeg"
-#define SA_CODEC_AC3 "ac3"
-#define SA_CODEC_GSM "gsm"
-#define SA_CODEC_VORBIS "vorbis"
-#define SA_CODEC_SPEEX "speex"
-
-/** Device opening modes */
-typedef enum {
-    SA_MODE_WRONLY = 1,
-    SA_MODE_RDONLY = 2,
-    SA_MODE_RDWR   = 3,
-    _SA_MODE_MAX   = 4
-} sa_mode_t;
-
-/** Error codes */
-typedef enum {
-    SA_SUCCESS = 0,
-    SA_ERROR_NOT_SUPPORTED = -1,
-    SA_ERROR_INVALID = -2,
-    SA_ERROR_STATE = -3,
-    SA_ERROR_OOM = -4,
-    SA_ERROR_NO_DEVICE = -5,
-    SA_ERROR_NO_DRIVER = -6,
-    SA_ERROR_NO_CODEC = -7,
-    SA_ERROR_NO_PCM_FORMAT = -7,
-    SA_ERROR_SYSTEM = -8,
-    SA_ERROR_NO_INIT = -9,
-    SA_ERROR_NO_META = -10,
-    SA_ERROR_NO_DATA = -11,
-    SA_ERROR_NO_SPACE = -12,
-    _SA_ERROR_MAX = -13
-} sa_error_t;
-
-/** Possible events for notifications */
-typedef enum {
-    SA_NOTIFY_REQUEST_START,
-    SA_NOTIFY_REQUEST_STOP,
-    SA_NOTIFY_CHANGED_READ_VOLUME,
-    SA_NOTIFY_CHANGED_WRITE_VOLUME,
-    SA_NOTIFY_CHANGED_DEVICE,
-    _SA_NOTIFY_MAX
-} sa_notify_t;
-
-/** Classes of events */
-typedef enum {
-    SA_EVENT_REQUEST_IO,
-    SA_EVENT_INIT_THREAD,
-    SA_EVENT_NOTIFY,
-    SA_EVENT_ERROR,
-    _SA_EVENT_MAX
-} sa_event_t;
-
-/** List of sample position queries */
-typedef enum {
-    SA_POSITION_WRITE_DELAY,
-    SA_POSITION_WRITE_HARDWARE,
-    SA_POSITION_WRITE_SOFTWARE,
-    SA_POSITION_READ_DELAY,
-    SA_POSITION_READ_HARDWARE,
-    SA_POSITION_READ_SOFTWARE,
-    SA_POSITION_DUPLEX_DELAY,
-    _SA_POSITION_MAX
-} sa_position_t;
-
-/* Channel positions */
-typedef enum {
-    SA_CHANNEL_MONO,
-    SA_CHANNEL_LEFT,
-    SA_CHANNEL_RIGHT,
-    SA_CHANNEL_CENTER,
-    SA_CHANNEL_FRONT_LEFT,
-    SA_CHANNEL_FRONT_RIGHT,
-    SA_CHANNEL_FRONT_CENTER,
-    SA_CHANNEL_REAR_LEFT,
-    SA_CHANNEL_REAR_RIGHT,
-    SA_CHANNEL_REAR_CENTER,
-    SA_CHANNEL_LFE,
-    SA_CHANNEL_FRONT_LEFT_OF_CENTER,
-    SA_CHANNEL_FRONT_RIGHT_OF_CENTER,
-    SA_CHANNEL_SIDE_LEFT,
-    SA_CHANNEL_SIDE_RIGHT,
-    SA_CHANNEL_TOP_CENTER,
-    SA_CHANNEL_TOP_FRONT_LEFT,
-    SA_CHANNEL_TOP_FRONT_RIGHT,
-    SA_CHANNEL_TOP_FRONT_CENTER,
-    SA_CHANNEL_TOP_REAR_LEFT,
-    SA_CHANNEL_TOP_REAR_RIGHT,
-    SA_CHANNEL_TOP_REAR_CENTER,
-    SA_CHANNEL_AUX0,
-    SA_CHANNEL_AUX1,
-    SA_CHANNEL_AUX2,
-    SA_CHANNEL_AUX3,
-    SA_CHANNEL_AUX4,
-    SA_CHANNEL_AUX5,
-    SA_CHANNEL_AUX6,
-    SA_CHANNEL_AUX7,
-    SA_CHANNEL_AUX8,
-    SA_CHANNEL_AUX9,
-    SA_CHANNEL_AUX10,
-    SA_CHANNEL_AUX11,
-    SA_CHANNEL_AUX12,
-    SA_CHANNEL_AUX13,
-    SA_CHANNEL_AUX14,
-    SA_CHANNEL_AUX15,
-    SA_CHANNEL_AUX16,
-    SA_CHANNEL_AUX17,
-    SA_CHANNEL_AUX18,
-    SA_CHANNEL_AUX19,
-    SA_CHANNEL_AUX20,
-    SA_CHANNEL_AUX21,
-    SA_CHANNEL_AUX22,
-    SA_CHANNEL_AUX23,
-    SA_CHANNEL_AUX24,
-    SA_CHANNEL_AUX25,
-    SA_CHANNEL_AUX26,
-    SA_CHANNEL_AUX27,
-    SA_CHANNEL_AUX28,
-    SA_CHANNEL_AUX29,
-    SA_CHANNEL_AUX30,
-    SA_CHANNEL_AUX31,
-    _SA_CHANNEL_MAX
-} sa_channel_t;
-
-typedef enum {
-    SA_STATE_INIT,
-    SA_STATE_RUNNING,
-    SA_STATE_STOPPED,
-    /* put more stuff */
-    _SA_STATE_MAX
-} sa_state_t;
-
-typedef enum {
-    SA_XRUN_MODE_STOP,
-    SA_XRUN_MODE_SPIN,
-    _SA_XRUN_MODE_MAX
-} sa_xrun_mode_t;
-
-typedef enum {
-    SA_ADJUST_UP = 1,
-    SA_ADJUST_DOWN = -1,
-    SA_ADJUST_NONE = 0
-} sa_adjust_t;
-
-/* Some kind of meta information.  */
-#define SA_META_CLIENT_NAME "sydney.client-name"     /* utf-8 */ 
-#define SA_META_PROCESS_ID "sydney.process-id"       /* getpid() */
-#define SA_META_LANGUAGE "sydney.language"           /* de_DE and similar */
-
-/* Some kind of meta information. Not filled in */
-#define SA_META_STREAM_NAME "sydney.stream-name"     /* utf-8 */ 
-#define SA_META_ICON_NAME "sydney.icon-name"         /* file name (no slashes) */
-#define SA_META_ICON_PNG "sydney.icon-png"           /* PNG blob */
-#define SA_META_ROLE "sydney.role"                   /* one of: "music", "phone", "game", "event" */
-#define SA_META_X11_DISPLAY "sydney.x11-display"     /* X11 display */
-#define SA_META_X11_WINDOW "sydney.x11-window"       /* X11 window id */
-
-/** Main callback function */
-typedef int (*sa_event_callback_t)(sa_stream_t *s, sa_event_t event);
-
-/** Create an opaque (e.g. AC3) codec stream */
-int sa_stream_create_opaque(sa_stream_t **s, const char *client_name, sa_mode_t mode, const char *codec);
-
-/** Normal way to open a PCM device */
-int sa_stream_create_pcm(sa_stream_t **s, const char *client_name, sa_mode_t mode, sa_pcm_format_t format, unsigned int rate, unsigned int nchannels);
-
-/** Initialise the device */
-int sa_stream_open(sa_stream_t *s);
-
-/** Close/destroy everything */
-int sa_stream_destroy(sa_stream_t *s);
-
-/* "Soft" params */
-int sa_stream_set_write_lower_watermark(sa_stream_t *s, size_t size);
-int sa_stream_set_read_lower_watermark(sa_stream_t *s, size_t size);
-int sa_stream_set_write_upper_watermark(sa_stream_t *s, size_t size);
-int sa_stream_set_read_upper_watermark(sa_stream_t *s, size_t size);
-
-/** Set the mapping between channels and the loudspeakers */
-int sa_stream_set_channel_map(sa_stream_t *s, const sa_channel_t map[], unsigned int n);
-
-/** Whether xruns cause the card to reset */
-int sa_stream_set_xrun_mode(sa_stream_t *s, sa_xrun_mode_t mode);
-
-/** Set the device to non-interleaved mode */
-int sa_stream_set_non_interleaved(sa_stream_t *s, int enable);
-
-/** Require dynamic sample rate */
-int sa_stream_set_dynamic_rate(sa_stream_t *s, int enable);
-
-/** Select driver */
-int sa_stream_set_driver(sa_stream_t *s, const char *driver);
-
-/** Start callback */
-int sa_stream_start_thread(sa_stream_t *s, sa_event_callback_t callback);
-
-/** Start callback */
-int sa_stream_stop_thread(sa_stream_t *s);
-
-/** Change the device connected to the stream */
-int sa_stream_change_device(sa_stream_t *s, const char *device_name);
-
-/** volume in hundreths of dB*/
-int sa_stream_change_read_volume(sa_stream_t *s, const int32_t vol[], unsigned int n);
-
-/** volume in hundreths of dB*/
-int sa_stream_change_write_volume(sa_stream_t *s, const int32_t vol[], unsigned int n);
-
-/** Change the sampling rate */
-int sa_stream_change_rate(sa_stream_t *s, unsigned int rate);
-
-/** Change some meta data that is attached to the stream */
-int sa_stream_change_meta_data(sa_stream_t *s, const char *name, const void *data, size_t size);
-
-/** Associate opaque user data */
-int sa_stream_change_user_data(sa_stream_t *s, const void *value);
-
-/* Hardware-related. This is implementation-specific and hardware specific. */
-int sa_stream_set_adjust_rate(sa_stream_t *s, sa_adjust_t direction);
-int sa_stream_set_adjust_nchannels(sa_stream_t *s, sa_adjust_t direction);
-int sa_stream_set_adjust_pcm_format(sa_stream_t *s, sa_adjust_t direction);
-int sa_stream_set_adjust_watermarks(sa_stream_t *s, sa_adjust_t direction);
-
-/* Query functions */
-
-int sa_stream_get_mode(sa_stream_t *s, sa_mode_t *access_mode);
-int sa_stream_get_codec(sa_stream_t *s, char *codec, size_t *size);
-int sa_stream_get_pcm_format(sa_stream_t *s, sa_pcm_format_t *format);
-int sa_stream_get_rate(sa_stream_t *s, unsigned int *rate);
-int sa_stream_get_nchannels(sa_stream_t *s, int *nchannels);
-int sa_stream_get_user_data(sa_stream_t *s, void **value);
-int sa_stream_get_write_lower_watermark(sa_stream_t *s, size_t *size);
-int sa_stream_get_read_lower_watermark(sa_stream_t *s, size_t *size);
-int sa_stream_get_write_upper_watermark(sa_stream_t *s, size_t *size);
-int sa_stream_get_read_upper_watermark(sa_stream_t *s, size_t *size);
-int sa_stream_get_channel_map(sa_stream_t *s, sa_channel_t map[], unsigned int *n);
-int sa_stream_get_xrun_mode(sa_stream_t *s, sa_xrun_mode_t *mode);
-int sa_stream_get_non_interleaved(sa_stream_t *s, int *enabled);
-int sa_stream_get_dynamic_rate(sa_stream_t *s, int *enabled);
-int sa_stream_get_driver(sa_stream_t *s, char *driver_name, size_t *size);
-int sa_stream_get_device(sa_stream_t *s, char *device_name, size_t *size);
-int sa_stream_get_read_volume(sa_stream_t *s, int32_t vol[], unsigned int *n);
-int sa_stream_get_write_volume(sa_stream_t *s, int32_t vol[], unsigned int *n);
-int sa_stream_get_meta_data(sa_stream_t *s, const char *name, void*data, size_t *size);
-int sa_stream_get_adjust_rate(sa_stream_t *s, sa_adjust_t *direction);
-int sa_stream_get_adjust_nchannels(sa_stream_t *s, sa_adjust_t *direction);
-int sa_stream_get_adjust_pcm_format(sa_stream_t *s, sa_adjust_t *direction);
-int sa_stream_get_adjust_watermarks(sa_stream_t *s, sa_adjust_t *direction);
-
-/** Get current state of the audio device */
-int sa_stream_get_state(sa_stream_t *s, sa_state_t *state);
-
-/** Obtain the error code */
-int sa_stream_get_event_error(sa_stream_t *s, sa_error_t *error);
-
-/** Obtain the notification code */
-int sa_stream_get_event_notify(sa_stream_t *s, sa_notify_t *notify);
-
-/** sync/timing */
-int sa_stream_get_position(sa_stream_t *s, sa_position_t position, int64_t *pos);
-
-
-/* Blocking IO calls */
-
-/** Interleaved capture function */
-int sa_stream_read(sa_stream_t *s, void *data, size_t nbytes);
-/** Non-interleaved capture function */
-int sa_stream_read_ni(sa_stream_t *s, unsigned int channel, void *data, size_t nbytes);
-
-/** Interleaved playback function */
-int sa_stream_write(sa_stream_t *s, const void *data, size_t nbytes);
-/** Non-interleaved playback function */
-int sa_stream_write_ni(sa_stream_t *s, unsigned int channel, const void *data, size_t nbytes);
-/** Interleaved playback function with seek offset */
-int sa_stream_pwrite(sa_stream_t *s, const void *data, size_t nbytes, int64_t offset, sa_seek_t whence);
-/** Non-interleaved playback function with seek offset */
-int sa_stream_pwrite_ni(sa_stream_t *s, unsigned int channel, const void *data, size_t nbytes, int64_t offset, sa_seek_t whence);
-
-
-/** Query how much can be read without blocking */
-int sa_stream_get_read_size(sa_stream_t *s, size_t *size);
-/** Query how much can be written without blocking */
-int sa_stream_get_write_size(sa_stream_t *s, size_t *size);
-
-
-/* Control/xrun */
-
-/** Resume playing after a pause */
-int sa_stream_resume(sa_stream_t *s);
-
-/** Pause audio playback (do not empty the buffer) */
-int sa_stream_pause(sa_stream_t *s);
-
-/** Block until all audio has been played */
-int sa_stream_drain(sa_stream_t *s);
-
-/** Return a human readable error */
-const char *sa_strerror(int code);
-
-/* Extensions */
-int
-sa_stream_set_volume_abs(sa_stream_t *s, float vol);
-
-int
-sa_stream_get_volume_abs(sa_stream_t *s, float *vol);
-
-#endif
deleted file mode 100644
--- a/media/liboggplay_audio/sydney_audio_alsa.c
+++ /dev/null
@@ -1,709 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Initial Developer of the Original Code is
- * CSIRO
- * Portions created by the Initial Developer are Copyright (C) 2007
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s): Michael Martin
- *                 Chris Double (chris.double@double.co.nz)
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** *
- */
-#include <stdlib.h>
-#include <pthread.h>
-#include <alsa/asoundlib.h>
-#include "sydney_audio.h"
-
-/* ALSA implementation based heavily on sydney_audio_mac.c */
-
-/*
- * The audio interface is based on a "pull" I/O model, which means you
- * can't just provide a data buffer and tell the audio device to play; you must
- * register a callback and provide data as the device asks for it. To support
- * sydney audio's "write-to-play" style interface, we have to buffer up the
- * data as it arrives and feed it to the callback as required.
- *
- * This is handled by a simple linked list of buffers; data is always written
- * to the tail and read from the head. Each buffer tracks the start and end
- * positions of its contained data. Buffers are allocated when the tail buffer
- * fills, and freed when the head buffer empties. There is always at least one
- * buffer allocated.
- *
- *       s   e      s      e      s  e            + data read
- *    +++#####  ->  ########  ->  ####----        # data written
- *    ^                           ^               - empty
- *    bl_head                     bl_tail
- */
-
-typedef struct sa_buf sa_buf;
-struct sa_buf {
-  unsigned int      size;
-  unsigned int      start;
-  unsigned int      end;
-  sa_buf          * next;
-  unsigned char     data[0];
-};
-
-struct sa_stream {
-  snd_pcm_t*        output_unit;
-  pthread_t         thread_id;
-  pthread_mutex_t   mutex;
-  char              playing;
-  int64_t           bytes_played;
-
-  /* audio format info */
-  unsigned int      rate;
-  unsigned int      n_channels;
-  unsigned int      bytes_per_ch;
-
-  /* buffer list */
-  sa_buf          * bl_head;
-  sa_buf          * bl_tail;
-  int               n_bufs;
-};
-
-
-/*
- * Use a default buffer size with enough room for one second of audio,
- * assuming stereo data at 44.1kHz with 32 bits per channel, and impose
- * a generous limit on the number of buffers.
- */
-#define BUF_SIZE    (2 * 44100 * 4)
-#define BUF_LIMIT   5
-
-#if BUF_LIMIT < 2
-#error BUF_LIMIT must be at least 2!
-#endif
-
-static void audio_callback(void* s);
-static sa_buf *new_buffer(void);
-
-
-/*
- * -----------------------------------------------------------------------------
- * Startup and shutdown functions
- * -----------------------------------------------------------------------------
- */
-
-int
-sa_stream_create_pcm(
-  sa_stream_t      ** _s,
-  const char        * client_name,
-  sa_mode_t           mode,
-  sa_pcm_format_t     format,
-  unsigned  int       rate,
-  unsigned  int       n_channels
-) {
-  sa_stream_t   * s = 0;
-
-  /*
-   * Make sure we return a NULL stream pointer on failure.
-   */
-  if (_s == NULL) {
-    return SA_ERROR_INVALID;
-  }
-  *_s = NULL;
-
-  if (mode != SA_MODE_WRONLY) {
-    return SA_ERROR_NOT_SUPPORTED;
-  }
-  if (format != SA_PCM_FORMAT_S16_LE) {
-    return SA_ERROR_NOT_SUPPORTED;
-  }
-
-  /*
-   * Allocate the instance and required resources.
-   */
-  if ((s = malloc(sizeof(sa_stream_t))) == NULL) {
-    return SA_ERROR_OOM;
-  }
-  if ((s->bl_head = new_buffer()) == NULL) {
-    free(s);
-    return SA_ERROR_OOM;
-  }
-  if (pthread_mutex_init(&s->mutex, NULL) != 0) {
-    free(s->bl_head);
-    free(s);
-    return SA_ERROR_SYSTEM;
-  }
-
-  s->output_unit  = NULL;
-  s->thread_id    = 0;
-  s->playing      = 0;
-  s->bytes_played = 0;
-  s->rate         = rate;
-  s->n_channels   = n_channels;
-  s->bytes_per_ch = 2;
-  s->bl_tail      = s->bl_head;
-  s->n_bufs       = 1;
-
-  *_s = s;
-  return SA_SUCCESS;
-}
-
-
-int
-sa_stream_open(sa_stream_t *s) {
-
-  if (s == NULL) {
-    return SA_ERROR_NO_INIT;
-  }
-  if (s->output_unit != NULL) {
-    return SA_ERROR_INVALID;
-  }
-
-  if (snd_pcm_open(&s->output_unit, 
-		   "default", 
-		   SND_PCM_STREAM_PLAYBACK, 
-		   0) < 0) {
-    return SA_ERROR_NO_DEVICE;
-  }
-  
-  if (snd_pcm_set_params(s->output_unit,
-			 SND_PCM_FORMAT_S16_LE,
-			 SND_PCM_ACCESS_RW_INTERLEAVED,
-			 s->n_channels,
-			 s->rate,
-			 1,
-			 0) < 0) {
-    snd_pcm_close(s->output_unit);
-    s->output_unit = NULL;
-    return SA_ERROR_NOT_SUPPORTED;
-  }
-
-  return SA_SUCCESS;
-}
-
-
-int
-sa_stream_destroy(sa_stream_t *s) {
-  int result = SA_SUCCESS;
-
-  if (s == NULL) {
-    return SA_SUCCESS;
-  }
-
-  pthread_mutex_lock(&s->mutex);
-
-  /*
-   * This causes the thread sending data to ALSA to stop
-   */
-  s->thread_id = 0;
-
-  /*
-   * Shut down the audio output device.
-   */
-  if (s->output_unit != NULL) {
-    if (s->playing && snd_pcm_close(s->output_unit) < 0) {
-      result = SA_ERROR_SYSTEM;
-    }
-  }
-
-  pthread_mutex_unlock(&s->mutex);
-
-  /*
-   * Release resources.
-   */
-  if (pthread_mutex_destroy(&s->mutex) != 0) {
-    result = SA_ERROR_SYSTEM;
-  }
-  while (s->bl_head != NULL) {
-    sa_buf  * next = s->bl_head->next;
-    free(s->bl_head);
-    s->bl_head = next;
-  }
-  free(s);
-
-  return result;
-}
-
-
-
-/*
- * -----------------------------------------------------------------------------
- * Data read and write functions
- * -----------------------------------------------------------------------------
- */
-
-int
-sa_stream_write(sa_stream_t *s, const void *data, size_t nbytes) {
-  int result = SA_SUCCESS;
-
-  if (s == NULL || s->output_unit == NULL) {
-    return SA_ERROR_NO_INIT;
-  }
-  if (nbytes == 0) {
-    return SA_SUCCESS;
-  }
-
-  pthread_mutex_lock(&s->mutex);
-
-  /*
-   * Append the new data to the end of our buffer list.
-   */
-  while (1) {
-    unsigned int avail = s->bl_tail->size - s->bl_tail->end;
-
-    if (nbytes <= avail) {
-
-      /*
-       * The new data will fit into the current tail buffer, so
-       * just copy it in and we're done.
-       */
-      memcpy(s->bl_tail->data + s->bl_tail->end, data, nbytes);
-      s->bl_tail->end += nbytes;
-      break;
-
-    } else {
-
-      /*
-       * Copy what we can into the tail and allocate a new buffer
-       * for the rest.
-       */
-      memcpy(s->bl_tail->data + s->bl_tail->end, data, avail);
-      s->bl_tail->end += avail;
-      data = ((unsigned char *)data) + avail;
-      nbytes -= avail;
-
-      /* 
-       * If we still have data left to copy but we've hit the limit of
-       * allowable buffer allocations, we need to spin for a bit to allow
-       * the audio callback function to slurp some more data up.
-       */
-      if (nbytes > 0 && s->n_bufs == BUF_LIMIT) {
-#ifdef TIMING_TRACE
-        printf("#");  /* too much audio data */
-#endif
-        if (!s->playing) {
-          /*
-           * We haven't even started playing yet! That means the
-           * BUF_SIZE/BUF_LIMIT values are too low... Not much we can
-           * do here; spinning won't help because the audio callback
-           * hasn't been enabled yet. Oh well, error time.
-           */
-          printf("Too much audio data received before audio device enabled!\n");
-          result = SA_ERROR_SYSTEM;
-          break;
-        }
-        while (s->n_bufs == BUF_LIMIT) {
-          struct timespec ts = {0, 1000000};
-          pthread_mutex_unlock(&s->mutex);
-          nanosleep(&ts, NULL);
-          pthread_mutex_lock(&s->mutex);
-        }
-      }
-
-      /* 
-       * Allocate a new tail buffer, and go 'round again to fill it up.
-       */
-      if ((s->bl_tail->next = new_buffer()) == NULL) {
-        result = SA_ERROR_OOM;
-        break;
-      }
-      s->n_bufs++;
-      s->bl_tail = s->bl_tail->next;
-    
-    } /* if (nbytes <= avail), else */
-
-  } /* while (1) */
-
-  pthread_mutex_unlock(&s->mutex);
-
-  /*
-   * Once we have our first block of audio data, enable the audio callback
-   * function. This doesn't need to be protected by the mutex, because
-   * s->playing is not used in the audio callback thread, and it's probably
-   * better not to be inside the lock when we enable the audio callback.
-   */
-  if (!s->playing) {
-    s->playing = 1;
-    if (pthread_create(&s->thread_id, NULL, (void *)audio_callback, s) != 0) {
-      result = SA_ERROR_SYSTEM;
-    }
-  }
-
-  return result;
-}
-
-
-static void audio_callback(void* data)
-{
-  sa_stream_t* s = (sa_stream_t*)data;
-  snd_pcm_uframes_t buffer_size;
-  snd_pcm_uframes_t period_size;
-  unsigned int bytes_per_frame = s->n_channels * s->bytes_per_ch;
-  char* buffer = 0;
-
-#ifdef TIMING_TRACE
-  printf(".");  /* audio read 'tick' */
-#endif
-
-  snd_pcm_get_params(s->output_unit, &buffer_size, &period_size);
- 
-  buffer = malloc(period_size * bytes_per_frame);
- 
-  while(1) {
-   char* dst = buffer;
-   unsigned int bytes_to_copy   = period_size * bytes_per_frame;
-   snd_pcm_sframes_t frames;
-
-   pthread_mutex_lock(&s->mutex);
-   if (!s->thread_id)
-     break;
-
-    /*
-     * Consume data from the start of the buffer list.
-     */
-    while (1) {
-      unsigned int avail = s->bl_head->end - s->bl_head->start;
-      assert(s->bl_head->start <= s->bl_head->end);
-
-      if (avail >= bytes_to_copy) {
-	/*
-	 * We have all we need in the head buffer, so just grab it and go.
-	 */
-	memcpy(dst, s->bl_head->data + s->bl_head->start, bytes_to_copy);
-	s->bl_head->start += bytes_to_copy;
-	s->bytes_played += bytes_to_copy;
-	break;
-	
-      } else {
-	sa_buf* next = 0;
-	/*
-	 * Copy what we can from the head and move on to the next buffer.
-	 */
-	memcpy(dst, s->bl_head->data + s->bl_head->start, avail);
-	s->bl_head->start += avail;
-	dst += avail;
-	bytes_to_copy -= avail;
-	s->bytes_played += avail;
-
-	/*
-	 * We want to free the now-empty buffer, but not if it's also the
-	 * current tail. If it is the tail, we don't have enough data to fill
-	 * the destination buffer, so we'll just zero it out and give up.
-	 */
-	next = s->bl_head->next;
-	if (next == NULL) {
-#ifdef TIMING_TRACE
-	  printf("!");  /* not enough audio data */
-#endif
-	  memset(dst, 0, bytes_to_copy);
-	  break;
-	}
-	free(s->bl_head);
-	s->bl_head = next;
-	s->n_bufs--;
-	
-      } /* if (avail >= bytes_to_copy), else */
-      
-    } /* while (1) */
-    
-    pthread_mutex_unlock(&s->mutex);
-    
-    frames = snd_pcm_writei(s->output_unit, buffer, period_size);
-    if (frames < 0) {
-      frames = snd_pcm_recover(s->output_unit, frames, 1);
-      if (frames < 0) {
-	printf("snc_pcm_recover error: %s\n", snd_strerror(frames));
-      }
-      if(frames > 0 && frames < period_size)
-	printf("short write (expected %d, wrote %d)\n", (int)period_size, (int)frames);;
-    }
-  }
-  free(buffer);
-}
-
-
-
-/*
- * -----------------------------------------------------------------------------
- * General query and support functions
- * -----------------------------------------------------------------------------
- */
-
-int
-sa_stream_get_write_size(sa_stream_t *s, size_t *size) {
-  sa_buf  * b;
-  size_t    used = 0;
-
-  if (s == NULL || s->output_unit == NULL) {
-    return SA_ERROR_NO_INIT;
-  }
-
-  pthread_mutex_lock(&s->mutex);
-
-  /*
-   * Sum up the used portions of our buffers and subtract that from
-   * the pre-defined max allowed allocation.
-   */
-  for (b = s->bl_head; b != NULL; b = b->next) {
-    used += b->end - b->start;
-  }
-  *size = BUF_SIZE * BUF_LIMIT - used;
-
-  pthread_mutex_unlock(&s->mutex);
-  return SA_SUCCESS;
-}
-
-
-int
-sa_stream_get_position(sa_stream_t *s, sa_position_t position, int64_t *pos) {
-
-  if (s == NULL || s->output_unit == NULL) {
-    return SA_ERROR_NO_INIT;
-  }
-  if (position != SA_POSITION_WRITE_SOFTWARE) {
-    return SA_ERROR_NOT_SUPPORTED;
-  }
-
-  pthread_mutex_lock(&s->mutex);
-  *pos = s->bytes_played;
-  pthread_mutex_unlock(&s->mutex);
-  return SA_SUCCESS;
-}
-
-
-int
-sa_stream_pause(sa_stream_t *s) {
-
-  if (s == NULL || s->output_unit == NULL) {
-    return SA_ERROR_NO_INIT;
-  }
-
-  pthread_mutex_lock(&s->mutex);
-#if 0 /* TODO */
-  AudioOutputUnitStop(s->output_unit);
-#endif
-  pthread_mutex_unlock(&s->mutex);
-  return SA_SUCCESS;
-}
-
-
-int
-sa_stream_resume(sa_stream_t *s) {
-
-  if (s == NULL || s->output_unit == NULL) {
-    return SA_ERROR_NO_INIT;
-  }
-
-  pthread_mutex_lock(&s->mutex);
-
-  /*
-   * The audio device resets its mSampleTime counter after pausing,
-   * so we need to clear our tracking value to keep that in sync.
-   */
-  s->bytes_played = 0;
-#if 0 /* TODO */
-  AudioOutputUnitStart(s->output_unit);
-#endif
-  pthread_mutex_unlock(&s->mutex);
-  return SA_SUCCESS;
-}
-
-
-static sa_buf *
-new_buffer(void) {
-  sa_buf  * b = malloc(sizeof(sa_buf) + BUF_SIZE);
-  if (b != NULL) {
-    b->size  = BUF_SIZE;
-    b->start = 0;
-    b->end   = 0;
-    b->next  = NULL;
-  }
-  return b;
-}
-
-
-
-/*
- * -----------------------------------------------------------------------------
- * Extension functions
- * -----------------------------------------------------------------------------
- */
-
-int
-sa_stream_set_volume_abs(sa_stream_t *s, float vol) {
-  snd_mixer_t* mixer = 0;
-  snd_mixer_elem_t* elem = 0;
-  if (s == NULL || s->output_unit == NULL) {
-    return SA_ERROR_NO_INIT;
-  }
-
-  if (snd_mixer_open(&mixer, 0) < 0) {
-    return SA_ERROR_SYSTEM;
-  }
-
-  if (snd_mixer_attach(mixer, "default") < 0) {
-    snd_mixer_close(mixer);
-    return SA_ERROR_SYSTEM;
-  }
-
-  if (snd_mixer_selem_register(mixer, NULL, NULL) < 0) {
-    snd_mixer_close(mixer);
-    return SA_ERROR_SYSTEM;
-  }
-
-  if (snd_mixer_load(mixer) < 0) {
-    snd_mixer_close(mixer);
-    return SA_ERROR_SYSTEM;
-  }
-
-#if 0
-  snd_mixer_elem_t* elem = 0;
-  for (elem = snd_mixer_first_elem(mixer); elem != NULL; elem = snd_mixer_elem_next(elem)) {
-    if (snd_mixer_selem_has_playback_volume(elem)) {
-      printf("Playback %s\n", snd_mixer_selem_get_name(elem));
-    }
-    else {
-      printf("No Playback: %s\n", snd_mixer_selem_get_name(elem));
-    }
-  }
-#endif
-  elem = snd_mixer_first_elem(mixer);
-  if (elem && snd_mixer_selem_has_playback_volume(elem)) {
-    long min = 0;
-    long max = 0;
-    if (snd_mixer_selem_get_playback_volume_range(elem, &min, &max) >= 0) {
-      snd_mixer_selem_set_playback_volume_all(elem, (max-min)*vol + min);
-    } 
-  }
-  snd_mixer_close(mixer);
-
-  return SA_SUCCESS;
-}
-
-
-int
-sa_stream_get_volume_abs(sa_stream_t *s, float *vol) {
-  snd_mixer_t* mixer = 0;
-  snd_mixer_elem_t* elem = 0;
-  long value = 0;
-
-  if (s == NULL || s->output_unit == NULL) {
-    return SA_ERROR_NO_INIT;
-  }
-
-  if (snd_mixer_open(&mixer, 0) < 0) {
-    return SA_ERROR_SYSTEM;
-  }
-
-  if (snd_mixer_attach(mixer, "default") < 0) {
-    snd_mixer_close(mixer);
-    return SA_ERROR_SYSTEM;
-  }
-
-  if (snd_mixer_selem_register(mixer, NULL, NULL) < 0) {
-    snd_mixer_close(mixer);
-    return SA_ERROR_SYSTEM;
-  }
-
-  if (snd_mixer_load(mixer) < 0) {
-    snd_mixer_close(mixer);
-    return SA_ERROR_SYSTEM;
-  }
-
-  elem = snd_mixer_first_elem(mixer);
-  if (elem && snd_mixer_selem_get_playback_volume(elem, 0, &value) >= 0) {
-    long min = 0;
-    long max = 0;
-    if (snd_mixer_selem_get_playback_volume_range(elem, &min, &max) >= 0) {
-      *vol = (float)(value-min)/(float)(max-min);
-    } 
-  }
-  snd_mixer_close(mixer);
-
-  return SA_SUCCESS;
-}
-
-
-
-/*
- * -----------------------------------------------------------------------------
- * Unsupported functions
- * -----------------------------------------------------------------------------
- */
-#define UNSUPPORTED(func)   func { return SA_ERROR_NOT_SUPPORTED; }
-
-UNSUPPORTED(int sa_stream_create_opaque(sa_stream_t **s, const char *client_name, sa_mode_t mode, const char *codec))
-UNSUPPORTED(int sa_stream_set_write_lower_watermark(sa_stream_t *s, size_t size))
-UNSUPPORTED(int sa_stream_set_read_lower_watermark(sa_stream_t *s, size_t size))
-UNSUPPORTED(int sa_stream_set_write_upper_watermark(sa_stream_t *s, size_t size))
-UNSUPPORTED(int sa_stream_set_read_upper_watermark(sa_stream_t *s, size_t size))
-UNSUPPORTED(int sa_stream_set_channel_map(sa_stream_t *s, const sa_channel_t map[], unsigned int n))
-UNSUPPORTED(int sa_stream_set_xrun_mode(sa_stream_t *s, sa_xrun_mode_t mode))
-UNSUPPORTED(int sa_stream_set_non_interleaved(sa_stream_t *s, int enable))
-UNSUPPORTED(int sa_stream_set_dynamic_rate(sa_stream_t *s, int enable))
-UNSUPPORTED(int sa_stream_set_driver(sa_stream_t *s, const char *driver))
-UNSUPPORTED(int sa_stream_start_thread(sa_stream_t *s, sa_event_callback_t callback))
-UNSUPPORTED(int sa_stream_stop_thread(sa_stream_t *s))
-UNSUPPORTED(int sa_stream_change_device(sa_stream_t *s, const char *device_name))
-UNSUPPORTED(int sa_stream_change_read_volume(sa_stream_t *s, const int32_t vol[], unsigned int n))
-UNSUPPORTED(int sa_stream_change_write_volume(sa_stream_t *s, const int32_t vol[], unsigned int n))
-UNSUPPORTED(int sa_stream_change_rate(sa_stream_t *s, unsigned int rate))
-UNSUPPORTED(int sa_stream_change_meta_data(sa_stream_t *s, const char *name, const void *data, size_t size))
-UNSUPPORTED(int sa_stream_change_user_data(sa_stream_t *s, const void *value))
-UNSUPPORTED(int sa_stream_set_adjust_rate(sa_stream_t *s, sa_adjust_t direction))
-UNSUPPORTED(int sa_stream_set_adjust_nchannels(sa_stream_t *s, sa_adjust_t direction))
-UNSUPPORTED(int sa_stream_set_adjust_pcm_format(sa_stream_t *s, sa_adjust_t direction))
-UNSUPPORTED(int sa_stream_set_adjust_watermarks(sa_stream_t *s, sa_adjust_t direction))
-UNSUPPORTED(int sa_stream_get_mode(sa_stream_t *s, sa_mode_t *access_mode))
-UNSUPPORTED(int sa_stream_get_codec(sa_stream_t *s, char *codec, size_t *size))
-UNSUPPORTED(int sa_stream_get_pcm_format(sa_stream_t *s, sa_pcm_format_t *format))
-UNSUPPORTED(int sa_stream_get_rate(sa_stream_t *s, unsigned int *rate))
-UNSUPPORTED(int sa_stream_get_nchannels(sa_stream_t *s, int *nchannels))
-UNSUPPORTED(int sa_stream_get_user_data(sa_stream_t *s, void **value))
-UNSUPPORTED(int sa_stream_get_write_lower_watermark(sa_stream_t *s, size_t *size))
-UNSUPPORTED(int sa_stream_get_read_lower_watermark(sa_stream_t *s, size_t *size))
-UNSUPPORTED(int sa_stream_get_write_upper_watermark(sa_stream_t *s, size_t *size))
-UNSUPPORTED(int sa_stream_get_read_upper_watermark(sa_stream_t *s, size_t *size))
-UNSUPPORTED(int sa_stream_get_channel_map(sa_stream_t *s, sa_channel_t map[], unsigned int *n))
-UNSUPPORTED(int sa_stream_get_xrun_mode(sa_stream_t *s, sa_xrun_mode_t *mode))
-UNSUPPORTED(int sa_stream_get_non_interleaved(sa_stream_t *s, int *enabled))
-UNSUPPORTED(int sa_stream_get_dynamic_rate(sa_stream_t *s, int *enabled))
-UNSUPPORTED(int sa_stream_get_driver(sa_stream_t *s, char *driver_name, size_t *size))
-UNSUPPORTED(int sa_stream_get_device(sa_stream_t *s, char *device_name, size_t *size))
-UNSUPPORTED(int sa_stream_get_read_volume(sa_stream_t *s, int32_t vol[], unsigned int *n))
-UNSUPPORTED(int sa_stream_get_write_volume(sa_stream_t *s, int32_t vol[], unsigned int *n))
-UNSUPPORTED(int sa_stream_get_meta_data(sa_stream_t *s, const char *name, void*data, size_t *size))
-UNSUPPORTED(int sa_stream_get_adjust_rate(sa_stream_t *s, sa_adjust_t *direction))
-UNSUPPORTED(int sa_stream_get_adjust_nchannels(sa_stream_t *s, sa_adjust_t *direction))
-UNSUPPORTED(int sa_stream_get_adjust_pcm_format(sa_stream_t *s, sa_adjust_t *direction))
-UNSUPPORTED(int sa_stream_get_adjust_watermarks(sa_stream_t *s, sa_adjust_t *direction))
-UNSUPPORTED(int sa_stream_get_state(sa_stream_t *s, sa_state_t *state))
-UNSUPPORTED(int sa_stream_get_event_error(sa_stream_t *s, sa_error_t *error))
-UNSUPPORTED(int sa_stream_get_event_notify(sa_stream_t *s, sa_notify_t *notify))
-UNSUPPORTED(int sa_stream_read(sa_stream_t *s, void *data, size_t nbytes))
-UNSUPPORTED(int sa_stream_read_ni(sa_stream_t *s, unsigned int channel, void *data, size_t nbytes))
-UNSUPPORTED(int sa_stream_write_ni(sa_stream_t *s, unsigned int channel, const void *data, size_t nbytes))
-UNSUPPORTED(int sa_stream_pwrite(sa_stream_t *s, const void *data, size_t nbytes, int64_t offset, sa_seek_t whence))
-UNSUPPORTED(int sa_stream_pwrite_ni(sa_stream_t *s, unsigned int channel, const void *data, size_t nbytes, int64_t offset, sa_seek_t whence))
-UNSUPPORTED(int sa_stream_get_read_size(sa_stream_t *s, size_t *size))
-UNSUPPORTED(int sa_stream_drain(sa_stream_t *s))
-
-const char *sa_strerror(int code) { return NULL; }
-
deleted file mode 100644
--- a/media/liboggplay_audio/sydney_audio_mac.c
+++ /dev/null
@@ -1,696 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Initial Developer of the Original Code is
- * CSIRO
- * Portions created by the Initial Developer are Copyright (C) 2007
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s): Michael Martin
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** *
- */
-
-#include <AudioUnit/AudioUnit.h>
-#include "sydney_audio.h"
-
-/*
- * The Mac's audio interface is based on a "pull" I/O model, which means you
- * can't just provide a data buffer and tell the audio device to play; you must
- * register a callback and provide data as the device asks for it. To support
- * sydney audio's "write-to-play" style interface, we have to buffer up the
- * data as it arrives and feed it to the callback as required.
- *
- * This is handled by a simple linked list of buffers; data is always written
- * to the tail and read from the head. Each buffer tracks the start and end
- * positions of its contained data. Buffers are allocated when the tail buffer
- * fills, and freed when the head buffer empties. There is always at least one
- * buffer allocated.
- *
- *       s   e      s      e      s  e            + data read
- *    +++#####  ->  ########  ->  ####----        # data written
- *    ^                           ^               - empty
- *    bl_head                     bl_tail
- */
-
-typedef struct sa_buf sa_buf;
-struct sa_buf {
-  unsigned int      size;
-  unsigned int      start;
-  unsigned int      end;
-  sa_buf          * next;
-  unsigned char     data[0];
-};
-
-struct sa_stream {
-  AudioUnit         output_unit;
-  pthread_mutex_t   mutex;
-  bool              playing;
-  int64_t           bytes_played;
-
-  /* audio format info */
-  unsigned int      rate;
-  unsigned int      n_channels;
-  unsigned int      bytes_per_ch;
-
-  /* buffer list */
-  sa_buf          * bl_head;
-  sa_buf          * bl_tail;
-  int               n_bufs;
-};
-
-
-/*
- * Use a default buffer size with enough room for one second of audio,
- * assuming stereo data at 44.1kHz with 32 bits per channel, and impose
- * a generous limit on the number of buffers.
- */
-#define BUF_SIZE    (2 * 44100 * 4)
-#define BUF_LIMIT   5
-
-#if BUF_LIMIT < 2
-#error BUF_LIMIT must be at least 2!
-#endif
-
-
-static OSStatus audio_callback(void *arg, AudioUnitRenderActionFlags *action_flags,
-  const AudioTimeStamp *time_stamp, UInt32 bus_num, UInt32 n_frames, AudioBufferList *data);
-
-static sa_buf *new_buffer(void);
-
-
-/*
- * -----------------------------------------------------------------------------
- * Startup and shutdown functions
- * -----------------------------------------------------------------------------
- */
-
-int
-sa_stream_create_pcm(
-  sa_stream_t      ** _s,
-  const char        * client_name,
-  sa_mode_t           mode,
-  sa_pcm_format_t     format,
-  unsigned  int       rate,
-  unsigned  int       n_channels
-) {
-
-  /*
-   * Make sure we return a NULL stream pointer on failure.
-   */
-  if (_s == NULL) {
-    return SA_ERROR_INVALID;
-  }
-  *_s = NULL;
-
-  if (mode != SA_MODE_WRONLY) {
-    return SA_ERROR_NOT_SUPPORTED;
-  }
-  if (format != SA_PCM_FORMAT_S16_LE) {
-    return SA_ERROR_NOT_SUPPORTED;
-  }
-
-  /*
-   * Allocate the instance and required resources.
-   */
-  sa_stream_t   * s;
-  if ((s = malloc(sizeof(sa_stream_t))) == NULL) {
-    return SA_ERROR_OOM;
-  }
-  if ((s->bl_head = new_buffer()) == NULL) {
-    free(s);
-    return SA_ERROR_OOM;
-  }
-  if (pthread_mutex_init(&s->mutex, NULL) != 0) {
-    free(s->bl_head);
-    free(s);
-    return SA_ERROR_SYSTEM;
-  }
-
-  s->output_unit  = NULL;
-  s->playing      = FALSE;
-  s->bytes_played = 0;
-  s->rate         = rate;
-  s->n_channels   = n_channels;
-  s->bytes_per_ch = 2;
-  s->bl_tail      = s->bl_head;
-  s->n_bufs       = 1;
-
-  *_s = s;
-  return SA_SUCCESS;
-}
-
-
-int
-sa_stream_open(sa_stream_t *s) {
-
-  if (s == NULL) {
-    return SA_ERROR_NO_INIT;
-  }
-  if (s->output_unit != NULL) {
-    return SA_ERROR_INVALID;
-  }
-
-  /*
-   * Open the default audio output unit.
-   */
-  ComponentDescription desc;
-  desc.componentType         = kAudioUnitType_Output;
-  desc.componentSubType      = kAudioUnitSubType_DefaultOutput;
-  desc.componentManufacturer = kAudioUnitManufacturer_Apple;
-  desc.componentFlags        = 0;
-  desc.componentFlagsMask    = 0;
-
-  Component comp = FindNextComponent(NULL, &desc);
-  if (comp == NULL) {
-    return SA_ERROR_NO_DEVICE;
-  }
-
-  if (OpenAComponent(comp, &s->output_unit) != noErr) {
-    return SA_ERROR_NO_DEVICE;
-  }
-
-  /*
-   * Set up the render callback used to feed audio data into the output unit.
-   */
-  AURenderCallbackStruct input;
-  input.inputProc       = audio_callback;
-  input.inputProcRefCon = s;
-  if (AudioUnitSetProperty(s->output_unit, kAudioUnitProperty_SetRenderCallback,
-      kAudioUnitScope_Input, 0, &input, sizeof(input)) != 0) {
-    return SA_ERROR_SYSTEM;
-  }
-
-  /*
-   * Set up the format description for our audio data. Apple uses the
-   * following terminology:
-   *
-   * sample = a single data value for one channel
-   * frame  = a set of samples that includes one sample for each channel
-   * packet = the smallest indivisible block of audio data; for uncompressed
-   *          audio (which is what we have), this is one frame
-   * rate   = the number of complete frames per second
-   *
-   * Note that this definition of frame differs from, well, pretty much everyone
-   * else's. See this really long link for more info:
-   *
-   * http://developer.apple.com/documentation/MusicAudio/Reference/CoreAudioDataTypesRef/Reference/reference.html#//apple_ref/c/tdef/AudioStreamBasicDescription
-   */
-  AudioStreamBasicDescription fmt;
-  fmt.mFormatID         = kAudioFormatLinearPCM;
-  fmt.mFormatFlags      = kLinearPCMFormatFlagIsSignedInteger |
-#ifdef __BIG_ENDIAN__
-                          kLinearPCMFormatFlagIsBigEndian |
-#endif
-                          kLinearPCMFormatFlagIsPacked;
-  fmt.mSampleRate       = s->rate;
-  fmt.mChannelsPerFrame = s->n_channels;
-  fmt.mBitsPerChannel   = s->bytes_per_ch * 8;
-  fmt.mFramesPerPacket  = 1;  /* uncompressed audio */
-  fmt.mBytesPerFrame    = fmt.mChannelsPerFrame * fmt.mBitsPerChannel / 8;
-  fmt.mBytesPerPacket   = fmt.mBytesPerFrame * fmt.mFramesPerPacket;
-
-  /*
-   * We're feeding data in to the output bus of the audio system, so we set
-   * the format description on the input scope of the device, using the very
-   * obvious element value of 0 to indicate the output bus.
-   *
-   * http://developer.apple.com/technotes/tn2002/tn2091.html
-   */
-  if (AudioUnitSetProperty(s->output_unit, kAudioUnitProperty_StreamFormat,
-      kAudioUnitScope_Input, 0, &fmt, sizeof(AudioStreamBasicDescription)) != 0) {
-    return SA_ERROR_NOT_SUPPORTED;
-  }
-
-  if (AudioUnitInitialize(s->output_unit) != 0) {
-    return SA_ERROR_SYSTEM;
-  }
-
-  return SA_SUCCESS;
-}
-
-
-int
-sa_stream_destroy(sa_stream_t *s) {
-
-  if (s == NULL) {
-    return SA_SUCCESS;
-  }
-
-  pthread_mutex_lock(&s->mutex);
-
-  /*
-   * Shut down the audio output device.
-   */
-  int result = SA_SUCCESS;
-  if (s->output_unit != NULL) {
-    if (s->playing && AudioOutputUnitStop(s->output_unit) != 0) {
-      result = SA_ERROR_SYSTEM;
-    }
-    if (AudioUnitUninitialize(s->output_unit) != 0) {
-      result = SA_ERROR_SYSTEM;
-    }
-    if (CloseComponent(s->output_unit) != noErr) {
-      result = SA_ERROR_SYSTEM;
-    }
-  }
-
-  pthread_mutex_unlock(&s->mutex);
-
-  /*
-   * Release resources.
-   */
-  if (pthread_mutex_destroy(&s->mutex) != 0) {
-    result = SA_ERROR_SYSTEM;
-  }
-  while (s->bl_head != NULL) {
-    sa_buf  * next = s->bl_head->next;
-    free(s->bl_head);
-    s->bl_head = next;
-  }
-  free(s);
-
-  return result;
-}
-
-
-
-/*
- * -----------------------------------------------------------------------------
- * Data read and write functions
- * -----------------------------------------------------------------------------
- */
-
-int
-sa_stream_write(sa_stream_t *s, const void *data, size_t nbytes) {
-
-  if (s == NULL || s->output_unit == NULL) {
-    return SA_ERROR_NO_INIT;
-  }
-  if (nbytes == 0) {
-    return SA_SUCCESS;
-  }
-
-  pthread_mutex_lock(&s->mutex);
-
-  /*
-   * Append the new data to the end of our buffer list.
-   */
-  int result = SA_SUCCESS;
-  while (1) {
-    unsigned int avail = s->bl_tail->size - s->bl_tail->end;
-
-    if (nbytes <= avail) {
-
-      /*
-       * The new data will fit into the current tail buffer, so
-       * just copy it in and we're done.
-       */
-      memcpy(s->bl_tail->data + s->bl_tail->end, data, nbytes);
-      s->bl_tail->end += nbytes;
-      break;
-
-    } else {
-
-      /*
-       * Copy what we can into the tail and allocate a new buffer
-       * for the rest.
-       */
-      memcpy(s->bl_tail->data + s->bl_tail->end, data, avail);
-      s->bl_tail->end += avail;
-      data = ((unsigned char *)data) + avail;
-      nbytes -= avail;
-
-      /* 
-       * If we still have data left to copy but we've hit the limit of
-       * allowable buffer allocations, we need to spin for a bit to allow
-       * the audio callback function to slurp some more data up.
-       */
-      if (nbytes > 0 && s->n_bufs == BUF_LIMIT) {
-#ifdef TIMING_TRACE
-        printf("#");  /* too much audio data */
-#endif
-        if (!s->playing) {
-          /*
-           * We haven't even started playing yet! That means the
-           * BUF_SIZE/BUF_LIMIT values are too low... Not much we can
-           * do here; spinning won't help because the audio callback
-           * hasn't been enabled yet. Oh well, error time.
-           */
-          printf("Too much audio data received before audio device enabled!\n");
-          result = SA_ERROR_SYSTEM;
-          break;
-        }
-        while (s->n_bufs == BUF_LIMIT) {
-          pthread_mutex_unlock(&s->mutex);
-          struct timespec ts = {0, 1000000};
-          nanosleep(&ts, NULL);
-          pthread_mutex_lock(&s->mutex);
-        }
-      }
-
-      /* 
-       * Allocate a new tail buffer, and go 'round again to fill it up.
-       */
-      if ((s->bl_tail->next = new_buffer()) == NULL) {
-        result = SA_ERROR_OOM;
-        break;
-      }
-      s->n_bufs++;
-      s->bl_tail = s->bl_tail->next;
-    
-    } /* if (nbytes <= avail), else */
-
-  } /* while (1) */
-
-  pthread_mutex_unlock(&s->mutex);
-
-  /*
-   * Once we have our first block of audio data, enable the audio callback
-   * function. This doesn't need to be protected by the mutex, because
-   * s->playing is not used in the audio callback thread, and it's probably
-   * better not to be inside the lock when we enable the audio callback.
-   */
-  if (!s->playing) {
-    s->playing = TRUE;
-    if (AudioOutputUnitStart(s->output_unit) != 0) {
-      result = SA_ERROR_SYSTEM;
-    }
-  }
-
-  return result;
-}
-
-
-static OSStatus
-audio_callback(
-  void                        * arg,
-  AudioUnitRenderActionFlags  * action_flags,
-  const AudioTimeStamp        * time_stamp,
-  UInt32                        bus_num,
-  UInt32                        n_frames,
-  AudioBufferList             * data
-) {
-
-#ifdef TIMING_TRACE
-  printf(".");  /* audio read 'tick' */
-#endif
-
-  /*
-   * We're dealing with interleaved data, so the system should only
-   * have provided one buffer to be filled.
-   */
-  assert(data->mNumberBuffers == 1);
-
-  sa_stream_t     * s = arg;
-
-  pthread_mutex_lock(&s->mutex);
-
-  unsigned char   * dst             = data->mBuffers[0].mData;
-  unsigned int      bytes_per_frame = s->n_channels * s->bytes_per_ch;
-  unsigned int      bytes_to_copy   = n_frames * bytes_per_frame;
-
-  /*
-   * Keep track of the number of bytes we've consumed so far. mSampleTime
-   * is actually the number of *frames* that have been consumed by the
-   * audio output unit so far. I don't know why it's a float.
-   */
-  assert(time_stamp->mFlags & kAudioTimeStampSampleTimeValid);
-  s->bytes_played = (int64_t)time_stamp->mSampleTime * bytes_per_frame;
-
-  /*
-   * Consume data from the start of the buffer list.
-   */
-  while (1) {
-    assert(s->bl_head->start <= s->bl_head->end);
-    unsigned int avail = s->bl_head->end - s->bl_head->start;
-
-    if (avail >= bytes_to_copy) {
-
-      /*
-       * We have all we need in the head buffer, so just grab it and go.
-       */
-      memcpy(dst, s->bl_head->data + s->bl_head->start, bytes_to_copy);
-      s->bl_head->start += bytes_to_copy;
-      break;
-
-    } else {
-
-      /*
-       * Copy what we can from the head and move on to the next buffer.
-       */
-      memcpy(dst, s->bl_head->data + s->bl_head->start, avail);
-      s->bl_head->start += avail;
-      dst += avail;
-      bytes_to_copy -= avail;
-
-      /*
-       * We want to free the now-empty buffer, but not if it's also the
-       * current tail. If it is the tail, we don't have enough data to fill
-       * the destination buffer, so we'll just zero it out and give up.
-       */
-      sa_buf  * next = s->bl_head->next;
-      if (next == NULL) {
-#ifdef TIMING_TRACE
-        printf("!");  /* not enough audio data */
-#endif
-        memset(dst, 0, bytes_to_copy);
-        break;
-      }
-      free(s->bl_head);
-      s->bl_head = next;
-      s->n_bufs--;
-
-    } /* if (avail >= bytes_to_copy), else */
-
-  } /* while (1) */
-
-  pthread_mutex_unlock(&s->mutex);
-  return noErr;
-}
-
-
-
-/*
- * -----------------------------------------------------------------------------
- * General query and support functions
- * -----------------------------------------------------------------------------
- */
-
-int
-sa_stream_get_write_size(sa_stream_t *s, size_t *size) {
-
-  if (s == NULL || s->output_unit == NULL) {
-    return SA_ERROR_NO_INIT;
-  }
-
-  pthread_mutex_lock(&s->mutex);
-
-  /*
-   * Sum up the used portions of our buffers and subtract that from
-   * the pre-defined max allowed allocation.
-   */
-  sa_buf  * b;
-  size_t    used = 0;
-  for (b = s->bl_head; b != NULL; b = b->next) {
-    used += b->end - b->start;
-  }
-  *size = BUF_SIZE * BUF_LIMIT - used;
-
-  pthread_mutex_unlock(&s->mutex);
-  return SA_SUCCESS;
-}
-
-
-int
-sa_stream_get_position(sa_stream_t *s, sa_position_t position, int64_t *pos) {
-
-  if (s == NULL || s->output_unit == NULL) {
-    return SA_ERROR_NO_INIT;
-  }
-  if (position != SA_POSITION_WRITE_SOFTWARE) {
-    return SA_ERROR_NOT_SUPPORTED;
-  }
-
-  pthread_mutex_lock(&s->mutex);
-  *pos = s->bytes_played;
-  pthread_mutex_unlock(&s->mutex);
-  return SA_SUCCESS;
-}
-
-
-int
-sa_stream_pause(sa_stream_t *s) {
-
-  if (s == NULL || s->output_unit == NULL) {
-    return SA_ERROR_NO_INIT;
-  }
-
-  pthread_mutex_lock(&s->mutex);
-  AudioOutputUnitStop(s->output_unit);
-  pthread_mutex_unlock(&s->mutex);
-  return SA_SUCCESS;
-}
-
-
-int
-sa_stream_resume(sa_stream_t *s) {
-
-  if (s == NULL || s->output_unit == NULL) {
-    return SA_ERROR_NO_INIT;
-  }
-
-  pthread_mutex_lock(&s->mutex);
-
-  /*
-   * The audio device resets its mSampleTime counter after pausing,
-   * so we need to clear our tracking value to keep that in sync.
-   */
-  s->bytes_played = 0;
-  AudioOutputUnitStart(s->output_unit);
-
-  pthread_mutex_unlock(&s->mutex);
-  return SA_SUCCESS;
-}
-
-
-static sa_buf *
-new_buffer(void) {
-  sa_buf  * b = malloc(sizeof(sa_buf) + BUF_SIZE);
-  if (b != NULL) {
-    b->size  = BUF_SIZE;
-    b->start = 0;
-    b->end   = 0;
-    b->next  = NULL;
-  }
-  return b;
-}
-
-
-
-/*
- * -----------------------------------------------------------------------------
- * Extension functions
- * -----------------------------------------------------------------------------
- */
-
-int
-sa_stream_set_volume_abs(sa_stream_t *s, float vol) {
-
-  if (s == NULL || s->output_unit == NULL) {
-    return SA_ERROR_NO_INIT;
-  }
-
-  pthread_mutex_lock(&s->mutex);
-  AudioUnitSetParameter(s->output_unit, kHALOutputParam_Volume,
-      kAudioUnitParameterFlag_Output, 0, vol, 0);
-  pthread_mutex_unlock(&s->mutex);
-  return SA_SUCCESS;
-}
-
-
-int
-sa_stream_get_volume_abs(sa_stream_t *s, float *vol) {
-
-  if (s == NULL || s->output_unit == NULL) {
-    return SA_ERROR_NO_INIT;
-  }
-
-  pthread_mutex_lock(&s->mutex);
-  Float32 local_vol = 0;
-  AudioUnitGetParameter(s->output_unit, kHALOutputParam_Volume,
-      kAudioUnitParameterFlag_Output, 0, &local_vol);
-  *vol = local_vol;
-  pthread_mutex_unlock(&s->mutex);
-  return SA_SUCCESS;
-}
-
-
-
-/*
- * -----------------------------------------------------------------------------
- * Unsupported functions
- * -----------------------------------------------------------------------------
- */
-#define UNSUPPORTED(func)   func { return SA_ERROR_NOT_SUPPORTED; }
-
-UNSUPPORTED(int sa_stream_create_opaque(sa_stream_t **s, const char *client_name, sa_mode_t mode, const char *codec))
-UNSUPPORTED(int sa_stream_set_write_lower_watermark(sa_stream_t *s, size_t size))
-UNSUPPORTED(int sa_stream_set_read_lower_watermark(sa_stream_t *s, size_t size))
-UNSUPPORTED(int sa_stream_set_write_upper_watermark(sa_stream_t *s, size_t size))
-UNSUPPORTED(int sa_stream_set_read_upper_watermark(sa_stream_t *s, size_t size))
-UNSUPPORTED(int sa_stream_set_channel_map(sa_stream_t *s, const sa_channel_t map[], unsigned int n))
-UNSUPPORTED(int sa_stream_set_xrun_mode(sa_stream_t *s, sa_xrun_mode_t mode))
-UNSUPPORTED(int sa_stream_set_non_interleaved(sa_stream_t *s, int enable))
-UNSUPPORTED(int sa_stream_set_dynamic_rate(sa_stream_t *s, int enable))
-UNSUPPORTED(int sa_stream_set_driver(sa_stream_t *s, const char *driver))
-UNSUPPORTED(int sa_stream_start_thread(sa_stream_t *s, sa_event_callback_t callback))
-UNSUPPORTED(int sa_stream_stop_thread(sa_stream_t *s))
-UNSUPPORTED(int sa_stream_change_device(sa_stream_t *s, const char *device_name))
-UNSUPPORTED(int sa_stream_change_read_volume(sa_stream_t *s, const int32_t vol[], unsigned int n))
-UNSUPPORTED(int sa_stream_change_write_volume(sa_stream_t *s, const int32_t vol[], unsigned int n))
-UNSUPPORTED(int sa_stream_change_rate(sa_stream_t *s, unsigned int rate))
-UNSUPPORTED(int sa_stream_change_meta_data(sa_stream_t *s, const char *name, const void *data, size_t size))
-UNSUPPORTED(int sa_stream_change_user_data(sa_stream_t *s, const void *value))
-UNSUPPORTED(int sa_stream_set_adjust_rate(sa_stream_t *s, sa_adjust_t direction))
-UNSUPPORTED(int sa_stream_set_adjust_nchannels(sa_stream_t *s, sa_adjust_t direction))
-UNSUPPORTED(int sa_stream_set_adjust_pcm_format(sa_stream_t *s, sa_adjust_t direction))
-UNSUPPORTED(int sa_stream_set_adjust_watermarks(sa_stream_t *s, sa_adjust_t direction))
-UNSUPPORTED(int sa_stream_get_mode(sa_stream_t *s, sa_mode_t *access_mode))
-UNSUPPORTED(int sa_stream_get_codec(sa_stream_t *s, char *codec, size_t *size))
-UNSUPPORTED(int sa_stream_get_pcm_format(sa_stream_t *s, sa_pcm_format_t *format))
-UNSUPPORTED(int sa_stream_get_rate(sa_stream_t *s, unsigned int *rate))
-UNSUPPORTED(int sa_stream_get_nchannels(sa_stream_t *s, int *nchannels))
-UNSUPPORTED(int sa_stream_get_user_data(sa_stream_t *s, void **value))
-UNSUPPORTED(int sa_stream_get_write_lower_watermark(sa_stream_t *s, size_t *size))
-UNSUPPORTED(int sa_stream_get_read_lower_watermark(sa_stream_t *s, size_t *size))
-UNSUPPORTED(int sa_stream_get_write_upper_watermark(sa_stream_t *s, size_t *size))
-UNSUPPORTED(int sa_stream_get_read_upper_watermark(sa_stream_t *s, size_t *size))
-UNSUPPORTED(int sa_stream_get_channel_map(sa_stream_t *s, sa_channel_t map[], unsigned int *n))
-UNSUPPORTED(int sa_stream_get_xrun_mode(sa_stream_t *s, sa_xrun_mode_t *mode))
-UNSUPPORTED(int sa_stream_get_non_interleaved(sa_stream_t *s, int *enabled))
-UNSUPPORTED(int sa_stream_get_dynamic_rate(sa_stream_t *s, int *enabled))
-UNSUPPORTED(int sa_stream_get_driver(sa_stream_t *s, char *driver_name, size_t *size))
-UNSUPPORTED(int sa_stream_get_device(sa_stream_t *s, char *device_name, size_t *size))
-UNSUPPORTED(int sa_stream_get_read_volume(sa_stream_t *s, int32_t vol[], unsigned int *n))
-UNSUPPORTED(int sa_stream_get_write_volume(sa_stream_t *s, int32_t vol[], unsigned int *n))
-UNSUPPORTED(int sa_stream_get_meta_data(sa_stream_t *s, const char *name, void*data, size_t *size))
-UNSUPPORTED(int sa_stream_get_adjust_rate(sa_stream_t *s, sa_adjust_t *direction))
-UNSUPPORTED(int sa_stream_get_adjust_nchannels(sa_stream_t *s, sa_adjust_t *direction))
-UNSUPPORTED(int sa_stream_get_adjust_pcm_format(sa_stream_t *s, sa_adjust_t *direction))
-UNSUPPORTED(int sa_stream_get_adjust_watermarks(sa_stream_t *s, sa_adjust_t *direction))
-UNSUPPORTED(int sa_stream_get_state(sa_stream_t *s, sa_state_t *state))
-UNSUPPORTED(int sa_stream_get_event_error(sa_stream_t *s, sa_error_t *error))
-UNSUPPORTED(int sa_stream_get_event_notify(sa_stream_t *s, sa_notify_t *notify))
-UNSUPPORTED(int sa_stream_read(sa_stream_t *s, void *data, size_t nbytes))
-UNSUPPORTED(int sa_stream_read_ni(sa_stream_t *s, unsigned int channel, void *data, size_t nbytes))
-UNSUPPORTED(int sa_stream_write_ni(sa_stream_t *s, unsigned int channel, const void *data, size_t nbytes))
-UNSUPPORTED(int sa_stream_pwrite(sa_stream_t *s, const void *data, size_t nbytes, int64_t offset, sa_seek_t whence))
-UNSUPPORTED(int sa_stream_pwrite_ni(sa_stream_t *s, unsigned int channel, const void *data, size_t nbytes, int64_t offset, sa_seek_t whence))
-UNSUPPORTED(int sa_stream_get_read_size(sa_stream_t *s, size_t *size))
-UNSUPPORTED(int sa_stream_drain(sa_stream_t *s))
-
-const char *sa_strerror(int code) { return NULL; }
-
deleted file mode 100644
--- a/media/liboggplay_audio/sydney_audio_oss.c
+++ /dev/null
@@ -1,640 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Initial Developer of the Original Code is
- * CSIRO
- * Portions created by the Initial Developer are Copyright (C) 2007
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s): Marcin Lubonski 
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** *
- */
-
-#include "sydney_audio.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/soundcard.h>
-
-#include <sys/ioctl.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <string.h>
-
-#define SA_READ_PERIOD 0 
-#define SA_WRITE_PERIOD 2560 // 40 ms of 16-bit, stereo, 16kHz
-#define SA_READ_BUFFER 0
-#define SA_WRITE_BUFFER 7680 // 3 periods per buffer
-
-// for versions newer than 3.6.1
-#define OSS_VERSION(x, y, z) (x << 16 | y << 8 | z)
-// support only versions newer than 3.6.1
-#define SUPP_OSS_VERSION OSS_VERSION(3,6,1)
-
-#if (SOUND_VERSION >= SUPP_OSS_VERSION)
-
-struct SAAudioHandle_ {
-   char *device_name;
-   int channels;
-   int read_period;
-   int write_period;
-   int read_buffer;
-   int write_buffer;
-   sa_pcm_mode_t rw_mode;
-   sa_pcm_format_t format;
-   int rate;
-   int interleaved;
-
-   int capture_handle;
-   int playback_handle;
-   int readN, writeN;
-   char *stored;
-   int stored_amount;
-   int stored_limit;
-   //int read_fd, write_fd;
-};
-
-/* Implemented API functions */
-/** Normal way to open PCM device */
-int sa_device_create_pcm(SAAudioHandle **_dev, const char *client_name, sa_pcm_mode_t rw_mode, sa_pcm_format_t format, int rate, int channels);
-/** Initialise the device */
-int sa_device_open(SAAudioHandle *dev);
-/** Close/destroy everything */
-int sa_device_close(SAAudioHandle *dev);
-
-/* Soft parameter setup - can only be called before calling open*/
-/** Set write buffer lower mark */
-int sa_device_set_write_lower_watermark(SAAudioHandle *dev, int size);
-/** Set read buffer lower mark */
-int sa_device_set_read_lower_watermark(SAAudioHandle *dev, int size);
-/** Set write buffer upper watermark */
-int sa_device_set_write_upper_watermark(SAAudioHandle *dev, int size);
-/** Set read buffer upper watermark */
-int sa_device_set_read_upper_watermark(SAAudioHandle *dev, int size);
-
-/** volume in hundreths of dB's*/
-int sa_device_change_input_volume(SAAudioHandle *dev, const int *vol);
-/** volume in hundreths of dB's*/
-int sa_device_change_output_volume(SAAudioHandle *dev, const int *vol);
-
-/** Read audio playback position */
-int sa_device_get_position(SAAudioHandle *dev, sa_pcm_index_t ref, int64_t *pos);
-
-/* Blocking I/O calls */
-/** Interleaved playback function */
-int sa_device_write(SAAudioHandle *dev, size_t nbytes, const void *data);
-
-
-/* Implementation-specific functions */
-static int oss_audio_format(sa_pcm_format_t sa_format, int* oss_format);
-//static void sa_print_handle_settings(SAAudioHandle* dev);
-
-/*!
- * \brief fills in the SAAudioHandle struct
- * \param SAAudioHandle - encapsulation of a handle to audio device
- * \param client_name - 
- * \param rw_mode - requested device access type as in :: sa_pcm_mode_t
- * \param format - audio format as specified in ::sa_pcm_format_t
- * \return - Sydney API error as in ::sa_pcm_error_t 
- */
-int sa_device_create_pcm(SAAudioHandle **_dev, const char *client_name, sa_pcm_mode_t rw_mode, sa_pcm_format_t format, int rate, int channels) {
-	SAAudioHandle* dev = NULL;
-	
-	dev = malloc(sizeof(SAAudioHandle));
-	
-	if (!dev) {
-		return SA_DEVICE_OOM;	
-	}		        
-	dev->channels = channels;
-	dev->format = format;
-	dev->rw_mode = rw_mode;
-	dev->rate = rate;
-	dev->readN = 0;
-	dev->readN = 0;
-	dev->capture_handle = -1;
-	dev->playback_handle = -1;
-	dev->interleaved = 1;
-	dev->read_period = SA_READ_PERIOD;
-	dev->write_period = SA_WRITE_PERIOD;
-	dev->read_buffer = SA_READ_BUFFER;
-	dev->write_buffer = SA_WRITE_BUFFER;
-  dev->device_name = "/dev/dsp";
-  dev->stored = NULL;
-  dev->stored_amount = 0;
-  dev->stored_limit = 0;
-	
-	*_dev = dev;
-	 //sa_print_handle_settings(dev);
-	 return SA_DEVICE_SUCCESS;
-}
-
-/*!
- * \brief creates and opens selected audio device
- * \param dev - encapsulated audio device handle
- * \return - Sydney API error as in ::sa_pcm_error_t  
- */
-int sa_device_open(SAAudioHandle *dev) {	
- 	int err;
-	int fmt;
-	int audio_fd = -1;
-
-	if (dev->rw_mode == SA_PCM_WRONLY) {
-		// open the default OSS device
-		dev->device_name = "/dev/dsp"; // replace with a function which returns audio ouput device best matching the settings
-		audio_fd = open(dev->device_name, O_WRONLY, 0);
-		if (audio_fd == -1) {
-		   fprintf(stderr, "Cannot open device: %s\n", dev->device_name);
-		   //assert(0);
-		   return SA_DEVICE_OOM;
-		}
-
-		// set the playback rate
-		if ((err = ioctl(audio_fd, SNDCTL_DSP_SPEED, &(dev->rate))) < 0) {
-		   fprintf(stderr, 
-			"Error setting the audio playback rate [%d]\n", 
-			dev->rate);
-		   //assert(0);
-		   return SA_DEVICE_OOM; 
-		}
-		// set the channel numbers
-		if ((err = ioctl(audio_fd,  SNDCTL_DSP_CHANNELS, 
-			&(dev->channels)))< 0) {
-		   fprintf(stderr, "Error setting audio channels\n");
-		   //assert(0);
-		   return SA_DEVICE_OOM;	
-		} 
-		if ((err = oss_audio_format(dev->format, &fmt)) < 0) {
-		   fprintf(stderr, "Format unknown\n");
-		   //assert(0);
-                   return SA_DEVICE_OOM;	   
-		}
-		printf("Setting format with value %d\n", fmt);
-		if ((err = ioctl(audio_fd, SNDCTL_DSP_SETFMT, &fmt)) < 0 ) {
-		   fprintf(stderr, "Error setting audio format\n");
-		   //assert(0);
-		   return SA_DEVICE_OOM;
-		}
-
-		dev->playback_handle = audio_fd;
- 		
-	}
-	if (dev->rw_mode == SA_PCM_RDONLY) {
-		return SA_DEVICE_NOT_SUPPORTED;
-	} 
-	if (dev->rw_mode == SA_PCM_RW) {
-		return SA_DEVICE_NOT_SUPPORTED;
-	}
-	fprintf(stderr, "Audio device opened successfully\n");
-	return SA_DEVICE_SUCCESS;
-}
-
-#define WRITE(data,amt)                                       \
-  if ((err = write(dev->playback_handle, data, amt)) < 0) {   \
-    fprintf(stderr, "Error writing data to audio device\n");  \
-    return SA_DEVICE_OOM;                                     \
-  }
-
-/*!
- * \brief Interleaved write operation
- * \param dev - device handle
- * \param nbytes - size of the audio buffer to be written to device
- * \param data - pointer to the buffer with audio samples
- * \return 
- * */
-int sa_device_write(SAAudioHandle *dev, size_t nbytes, const void *_data) {
-	int               err;
-  audio_buf_info    info;
-  int               bytes;
-  char            * data = (char *)_data;
-  /*
-  ioctl(dev->playback_handle, SNDCTL_DSP_GETOSPACE, &info);
-  printf("fragment size: %d, nfrags: %d, free: %d wtw: %d\n", info.fragsize, 
-                  info.fragstotal, info.bytes, nbytes);
-  */
-
-
-
-	if ((dev->playback_handle) > 0) {
-    ioctl(dev->playback_handle, SNDCTL_DSP_GETOSPACE, &info);
-    bytes = info.bytes;
-    if (dev->stored_amount > bytes) {
-      WRITE(dev->stored, bytes);
-      memmove(dev->stored, dev->stored + bytes, dev->stored_amount - bytes);
-      dev->stored_amount -= bytes;
-    } else if (dev->stored_amount > 0) {
-      WRITE(dev->stored, dev->stored_amount);
-      bytes -= dev->stored_amount;
-      dev->stored_amount = 0;
-      if (nbytes < bytes) {
-        WRITE(data, nbytes);
-        return SA_DEVICE_SUCCESS;
-      }
-      WRITE(data, bytes);
-      data += bytes;
-      nbytes -= bytes;
-    } else {
-      if (nbytes < bytes) {
-        WRITE(data, nbytes);
-        return SA_DEVICE_SUCCESS;
-      }
-      WRITE(data, bytes);
-      data += bytes;
-      nbytes -= bytes;
-    }
-
-    if (nbytes > 0) {
-      if (dev->stored_amount + nbytes > dev->stored_limit) {
-        dev->stored = realloc(dev->stored, dev->stored_amount + nbytes);
-      }
-      
-      memcpy(dev->stored + dev->stored_amount, data, nbytes);
-      dev->stored_amount += nbytes;
-    }
-	}
-	return SA_DEVICE_SUCCESS;
-}
-
-#define CLOSE_HANDLE(x) if (x != -1) close(x);
-
-/*!
- * \brief Closes and destroys allocated resources
- * \param dev - Sydney Audio device handle
- * \return Sydney API error as in ::sa_pcm_error_t
- **/
-int sa_device_close(SAAudioHandle *dev) {
-  int err;
-
-	if (dev != NULL) {
-
-    if (dev->stored_amount > 0) {
-      WRITE(dev->stored, dev->stored_amount);
-    }
-
-    if (dev->stored != NULL) {
-      free(dev->stored);
-    }
-
-    dev->stored = NULL;
-    dev->stored_amount = 0;
-    dev->stored_limit = 0;
-	  
-    CLOSE_HANDLE(dev->playback_handle);
-	  CLOSE_HANDLE(dev->capture_handle);
-
-	  printf("Closing audio device\n");	
-	  free(dev);
-	}
- 	return SA_DEVICE_SUCCESS;
-}
-
-/** 
- * \brief 
- * \param dev
- * \param size
- * \return  Sydney API error as in ::sa_pcm_error_t
- */
-int sa_device_set_write_lower_watermark(SAAudioHandle *dev, int size) {
-   dev->write_period = size;
-   return SA_DEVICE_SUCCESS;
-}
-/** 
- * \brief
- * \param dev
- * \param size
- * \return  Sydney API error as in ::sa_pcm_error_t
- */
-int sa_device_set_read_lower_watermark(SAAudioHandle *dev, int size) {
-   dev->read_period = size;
-   return SA_DEVICE_SUCCESS;
-}
-/** 
- * \brief
- * \param dev
- * \param size
- * \return  Sydney API error as in ::sa_pcm_error_t
- */
-int sa_device_set_write_upper_watermark(SAAudioHandle *dev, int size) {  
-   dev->write_buffer = size;
-   return SA_DEVICE_SUCCESS;
-}
-
-/** 
- * \brief
- * \param dev
- * \param size
- * \return  Sydney API error as in ::sa_pcm_error_t
- */
-int sa_device_set_read_upper_watermark(SAAudioHandle *dev, int size) {
-   dev->read_buffer = size;
-   return SA_DEVICE_SUCCESS;
-}
-
-
-int sa_device_set_xrun_mode(SAAudioHandle *dev, sa_xrun_mode_t mode) {
-   return SA_DEVICE_NOT_SUPPORTED;
-}
-
-
-int sa_device_set_ni(SAAudioHandle *dev) {
-   dev->interleaved = 1;
-   return SA_DEVICE_SUCCESS;
-}
-
-int sa_device_start_thread(SAAudioHandle *dev, sa_device_callback *callback) {
-   return SA_DEVICE_NOT_SUPPORTED;
-}
-
-int sa_device_set_channel_map(SAAudioHandle *dev, const sa_channel_def_t *map) {
-   return SA_DEVICE_NOT_SUPPORTED;
-}
-
-
-int sa_device_change_device(SAAudioHandle *dev, const char *device_name) {
-   return SA_DEVICE_NOT_SUPPORTED;
-}
-
-/*!
- * \brief volume in hundreths of dB's
- * \param dev - device handle
- * \param vol - volume level 
- * \return Sydney API error as in ::sa_pcm_error_t
- * */
-int sa_device_change_input_volume(SAAudioHandle *dev, const int *vol) {
-#if SOUND_VERSION >= OSS_VERSION(4,0,0)	
-	int err;
-	if ((err = ioctl(dev->capture_handle, SNDCTL_DSP_SETRECVOL, vol) < 0) {
-	   fpritnf(stderr, "Error setting new recording volume level\n");
-	   //assert(0);
-           return SA_DEVICE_OOM;	   
-	}
-	return SA_DEVICE_SUCCESS;
-#else
-	return SA_DEVICE_NOT_SUPPORTED;
-#endif
-}
-
-/*!
- * \brief volume in hundreths of dB's
- * \param dev - device handle
- * \param vol - volume level
- * \retrun  Sydney API error as in ::sa_pcm_error_t
- * */
-int sa_device_change_output_volume(SAAudioHandle *dev, const int *vol) {
-#if SOUND_VERSION >= OSS_VERSION(4,0,0)
-	int err;
-	if ((err = ioctl(dev->playback_handle, SNDCTL_DSP_SETPLAYVOL, vol) < 0){
-
-	fprintf(stderr, "Error setting new playback volume\n");
-	//assert(0);
-	return SA_DEVICE_OOM; 
-        }
-	return SA_DEVICE_SUCCESS;
-#else
-	return SA_DEVICE_NOT_SUPPORTED;
-#endif
-}
-
-int sa_device_change_sampling_rate(SAAudioHandle *dev, int rate) {
-   dev->rate = rate;
-   return SA_DEVICE_SUCCESS;
-}
-
-int sa_device_change_client_name(SAAudioHandle *dev, const char *client_name) {
-   return SA_DEVICE_NOT_SUPPORTED;
-}
-
-int sa_device_change_stream_name(SAAudioHandle *dev, const char *stream_name) {
-   return SA_DEVICE_NOT_SUPPORTED;
-}
-
-int sa_device_change_user_data(SAAudioHandle *dev, void *val) {
-   return SA_DEVICE_NOT_SUPPORTED;
-}
-
-
-/*!
- * \brief
- * \param dev
- * \param rate
- * \param direction
- * \return  Sydney API error as in ::sa_pcm_error_t
- * */
-int sa_device_adjust_rate(SAAudioHandle *dev, int rate, int direction) {
-   return  SA_DEVICE_NOT_SUPPORTED;
-}
-/*!
- * \brief
- * \param dev
- * \param nb_channels
- * \return  Sydney API error as in ::sa_pcm_error_t
- * */
-int sa_device_adjust_channels(SAAudioHandle *dev, int nb_channels) {               return SA_DEVICE_NOT_SUPPORTED;
-}
-/** Adjust bit sample format */
-int sa_device_adjust_format(SAAudioHandle *dev, sa_pcm_format_t format, int direction) {
-   return SA_DEVICE_NOT_SUPPORTED;
-}
-
-/** Get current state of the audio device */
-int sa_device_get_state(SAAudioHandle *dev, sa_state_t *running) {
-   return SA_DEVICE_NOT_SUPPORTED;
-}
-
-/** Get current sampling rate */
-int sa_device_get_sampling_rate(SAAudioHandle *dev, int *rate) {
-   return SA_DEVICE_NOT_SUPPORTED;
-}
-
-/** Get number of channels */
-int sa_device_get_nb_channels(SAAudioHandle *dev, int *nb_channels) {
-   return SA_DEVICE_NOT_SUPPORTED;
-}
-
-/** Get format being used */
-int sa_device_get_format(SAAudioHandle *dev, sa_pcm_format_t *format) {
-   return SA_DEVICE_NOT_SUPPORTED;
-}
-
-/** Get opaque pointer associated to the device */
-int sa_device_get_user_data(SAAudioHandle *dev, void **val) {
-   return SA_DEVICE_NOT_SUPPORTED;
-}
-
-/** Obtain the error code */
-int sa_device_get_event_error(SAAudioHandle *dev, sa_pcm_error_t *error) {
-   return SA_DEVICE_NOT_SUPPORTED;
-}
-
-/** Obtain the notification code */
-int sa_device_get_event_notify(SAAudioHandle *dev, sa_pcm_notification_t *notify) {
-   return SA_DEVICE_NOT_SUPPORTED;
-}
-
-/*!
- * \brief returns the current position of the audio playback capture
- * \param dev - device handle
- * \param ref - type of position to be returned by this function see ::sa_pcm_index_t
- * \param pos - position (in bytes or ms depending on 'ref' value)
- * \return  Sydney API error as in ::sa_pcm_error_t
- * */
-int sa_device_get_position(SAAudioHandle *dev, sa_pcm_index_t ref, int64_t *pos)
-{
-   int err;
-   int64_t _pos;
-   int delay;
-   count_info ptr;
-   switch (ref) {
-	 case SA_PCM_WRITE_DELAY:
-	      //int delay;
-	      if ((err = ioctl(dev->playback_handle, 
-			       SNDCTL_DSP_GETODELAY, 
- 			       &delay)) <0) {
-	      	fprintf(stderr, "Error reading playback buffering delay\n");
-		return SA_DEVICE_OOM;	
-	      };  
-	      _pos = (int64_t)delay;
-	      break;
-         case SA_PCM_WRITE_SOFTWARE_POS:
-              //count_info ptr;
-	      if ((err = ioctl(dev->playback_handle, 
-                               SNDCTL_DSP_GETOPTR, 
-                               &ptr)) <0) {
-                //fprintf(stderr, "Error reading audio playback position\n");
-		return SA_DEVICE_OOM;
-              };
-	      _pos = (int64_t)ptr.bytes;  
-	      break;
-         case SA_PCM_READ_SOFTWARE_POS:
-              //count_info ptr;
-	      if ((err = ioctl(dev->playback_handle, 
-                               SNDCTL_DSP_GETIPTR, 
-                               &ptr)) <0) {
-              	 fprintf(stderr, "Error reading audio capture position\n");
-		 return SA_DEVICE_OOM;
-	      };
-               _pos = (int64_t)ptr.bytes;
-	      break;
-
-	 case SA_PCM_READ_DELAY:
-	 case SA_PCM_READ_HARDWARE_POS:
-	 case SA_PCM_WRITE_HARDWARE_POS:               
-	 case SA_PCM_DUPLEX_DELAY:
-	 default:
-	      return SA_DEVICE_NOT_SUPPORTED;
-	      break;		
-   }
-   (*pos) = _pos;
-   return SA_DEVICE_SUCCESS;
-}
-
-/** Private functions - implementation specific */
-
-/*!
- * \brief private function mapping Sudney Audio format to OSS formats
- * \param format - Sydney Audio API specific format
- * \param - filled by the function with a value for corresponding OSS format
- * \return - Sydney API error value as in ::sa_pcm_format_t
- * */
-static int oss_audio_format(sa_pcm_format_t sa_format, int* oss_format) {
-#if SOUND_VERSION >= OSS_VERSION(4,0,0) 	
-	int fmt = AFMT_UNDEF;
-#else
-	int fmt = -1;
-#endif	
-	switch (sa_format) {
-                   case SA_PCM_UINT8:
-			fmt = AFMT_U8;
-			break;
-                   case SA_PCM_ULAW:
-			fmt = AFMT_MU_LAW;
-			break;
-                   case SA_PCM_ALAW:
-			fmt = AFMT_A_LAW;
-			break;
-		   /* 16-bit little endian (LE) format */
-                   case SA_PCM_S16_LE:
-			fmt = AFMT_S16_LE;
-			break;
-		   /* 16-bit big endian (BE) format */
-                   case SA_PCM_S16_BE:
-			fmt = AFMT_S16_BE;
-			break;
-#if SOUND_VERSION >= OSS_VERSION(4,0,0)
-		   /* 24-bit formats (LSB aligned in 32 bit word) */
-                   case SA_PCM_S24_LE:
-			fmt = AFMT_S24_LE;
-			break;
-		   /* 24-bit formats (LSB aligned in 32 bit word) */
-		   case SA_PCM_S24_BE:
-			fmt = AFMT_S24_BE;
-			break;
-		   /* 32-bit format little endian */
-                   case SA_PCM_S32_LE:
-			fmt = AFMT_S32_LE;
-			break;
-		   /* 32-bit format big endian */
-                   case SA_PCM_S32_BE:
-			fmt = AFMT_S32_BE;
-			break; 
-                   case SA_PCM_FLOAT32_NE:
-			fmt = AFMT_FLOAT;
-			break;
-#endif
-		   default:
-			return SA_DEVICE_NOT_SUPPORTED;
-			break;
-
-                }
-	(*oss_format) = fmt;
-	return SA_DEVICE_SUCCESS;
-}
-
-/*
-static void sa_print_handle_settings(SAAudioHandle* dev) {
-    printf(">>>>>>>>>>>> SA Device Handle <<<<<<<<<<<\n"); 
-    printf("[SA Audio] - Device name %s\n", dev->device_name);
-    printf("[SA_Audio] - Number of audio channels %d\n", dev->channels);
-    printf("[SA_Audio] - Read period size %d bytes\n", dev->read_period);
-    printf("[SA_Audio] - Write period size %d bytes\n", dev->write_period);
-    printf("[SA_Audio] - Write buffer size %d bytes\n", dev->write_buffer);
-    printf("[SA_Audio] - Read buffer size %d bytes\n", dev->read_buffer);
-    printf("[SA_Audio] - Read/write mode value %d\n", dev->rw_mode);
-    printf("[SA_Audio] - Audio sample bit format value %d\n", dev->format);
-    printf("[SA_Audio] - Audio playback rate %d\n", dev->rate);
-    if (dev->interleaved) {
-        printf("[SA_Audio] - Processing interleaved audio\n");
-    } else {
-	printf("[SA_Audio] - Processing non-interleaved audio\n");
-    }
-    if ((dev->capture_handle) > 0) {
-    	printf("[SA Audio] - Device opened for capture\n");
-    } 
-    if ((dev->playback_handle) > 0) {
-    	printf("[SA_Audio] - Device opened for playback\n");
-    }	    
-}
-*/
-
-#endif // (SOUND_VERSION > SUPP_OSS_VERSION)
deleted file mode 100644
--- a/media/liboggplay_audio/sydney_audio_waveapi.c
+++ /dev/null
@@ -1,681 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Initial Developer of the Original Code is
- * CSIRO
- * Portions created by the Initial Developer are Copyright (C) 2007
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s): Marcin Lubonski 
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** *
- */
-
-#include "sydney_audio.h"
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <windows.h>
-#include <mmreg.h>
-#include <mmsystem.h>
-#include <math.h>
-
-
-// FIX ME: block size and block should be determined based on the OggPlay offset 
-// for audio track
-#define BLOCK_SIZE  2560
-#define BLOCK_COUNT 32
-#define DEFAULT_DEVICE_NAME "Default WAVE Device"
-#define DEFAULT_DEVICE WAVE_MAPPER
-
-#define VERBOSE_OUTPUT 1
-
-// INFO: if you get weird compile errors make sure there is no extra chars pass '\' 
-#if defined(VERBOSE_OUTPUT)
-#define WAVE_ERROR_VERBOSE(error, message) \
-  switch (error) { \
-    case MMSYSERR_ALLOCATED: \
-      printf("[WAVE API] Device allocation error returned while executing %s\n", message); \
-      break; \
-    case MMSYSERR_BADDEVICEID: \
-      printf("[WAVE API] Wrong device ID error returned while executing %s\n", message); \
-      break; \
-    case MMSYSERR_NODRIVER: \
-      printf("[WAVE API] System driver not present error returned while executing %s\n", message); \
-      break; \
-    case MMSYSERR_INVALHANDLE: \
-      printf("[WAVE API] Invalid device handle error returned while executing %s\n", message); \
-      break; \
-    case MMSYSERR_NOMEM: \
-      printf("[WAVE API] No memory error returned while executing %s\n", message); \
-      break; \
-    case MMSYSERR_NOTSUPPORTED: \
-      printf("[WAVE API] Not supported error returned while executing %s\n", message); \
-      break; \
-    case WAVERR_BADFORMAT: \
-      printf("[WAVE API] Not valid audio format returned while executing %s\n", message); \
-      break; \
-    case WAVERR_SYNC: \
-      printf("[WAVE API] Device synchronous error returned while executing %s\n", message); \
-      break; \
-    default: \
-      printf("[WAVE API] Error while executing %s\n", message); \
-      break; \
-  }
-#else
-#define WAVE_ERROR_VERBOSE(error, message) \
-  do {} while(0)
-#endif
-
-#define HANDLE_WAVE_ERROR(status, location) \
-  if (status != MMSYSERR_NOERROR) { \
-      WAVE_ERROR_VERBOSE(status, location); \
-      return getSAErrorCode(status); \
-  }
-
-#define ERROR_IF_NO_INIT(handle) \
-  if (handle == NULL) { \
-		return SA_ERROR_NO_INIT; \
-	}
-
-/* local implementation of the sa_stream_t type */
-struct sa_stream {   
-  char*           deviceName;
-  UINT				    device;
-  UINT				    channels;
-  UINT				    rate;
-	
-  sa_mode_t			  rwMode;
-  sa_pcm_format_t	format;   
- 
-  HWAVEOUT			  hWaveOut;
-  HANDLE			    callbackEvent;
-  CRITICAL_SECTION  waveCriticalSection;  
-  WAVEHDR*			  waveBlocks;  
-  volatile int		waveFreeBlockCount;
-  int				      waveCurrentBlock;
-};
-
-
-/** Forward definitions of audio api specific functions */
-int allocateBlocks(int size, int count, WAVEHDR** blocks);
-int freeBlocks(WAVEHDR* blocks);
-int openAudio(sa_stream_t *s);
-int closeAudio(sa_stream_t * s);
-int writeAudio(sa_stream_t *s, LPSTR data, int bytes);
-int getSAErrorCode(int waveErrorCode);
-
-void CALLBACK waveOutProc(HWAVEOUT hWaveOut, UINT uMsg, 
-    DWORD dwInstance, DWORD dwParam1, DWORD dwParam2);
-
-/** Normal way to open a PCM device */
-int sa_stream_create_pcm(sa_stream_t **s, 
-                         const char *client_name, 
-                         sa_mode_t mode, 
-                         sa_pcm_format_t format, 
-                         unsigned int rate, 
-                         unsigned int nchannels) {
-  sa_stream_t * _s = NULL;
-  
-  ERROR_IF_NO_INIT(s);
-  
-  *s = NULL;
-  
-  /* FIX ME: for formats different than PCM extend using WAVEFORMATEXTENSIBLE */
-  if (format != SA_PCM_FORMAT_S16_NE) {
-    return SA_ERROR_NOT_SUPPORTED;
-  }
-
-  if (mode != SA_MODE_WRONLY) {
-    return SA_ERROR_NOT_SUPPORTED;
-  }
-
-  if ((_s = (sa_stream_t*)malloc(sizeof(sa_stream_t))) == NULL) {
-    return SA_ERROR_OOM;
-  }
-   
-  _s->rwMode = mode;
-  _s->format = format;
-  _s->rate = rate;
-  _s->channels = nchannels;
-  _s->deviceName = DEFAULT_DEVICE_NAME;
-  _s->device = DEFAULT_DEVICE;
-
-  *s = _s; 
-  return SA_SUCCESS;
-}
-
-/** Initialise the device */
-int sa_stream_open(sa_stream_t *s) {  
-  int status = SA_SUCCESS;
-
-  ERROR_IF_NO_INIT(s);
-
-  switch (s->rwMode) {
-    case SA_MODE_WRONLY: 
-      status = openAudio(s);
-      break;
-	default:
-      status = SA_ERROR_NOT_SUPPORTED;      
-      break;
-  }    
-  return status;
-}
-
-/** Interleaved playback function */
-int sa_stream_write(sa_stream_t *s, const void *data, size_t nbytes) {
-  int status = SA_SUCCESS;
-
-  ERROR_IF_NO_INIT(s);
-
-  status = writeAudio(s, (LPSTR)data, nbytes);
-
-  return status;
-}
-
-/** Close/destroy everything */
-int sa_stream_destroy(sa_stream_t *s) {
-  int status;
-
-  ERROR_IF_NO_INIT(s);
-  /* close and release all allocated resources */
-  status = closeAudio(s);
-
-  return status;
-}
-
-#define LEFT_CHANNEL_MASK 0x0000FFFF
-#define RIGHT_CHANNEL_MASK 0xFFFF0000
-
-/** 
- * retrieved volume as an int in a scale from 0x0000 to 0xFFFF
- * only one value for all channels
- */
-int sa_stream_get_write_volume(sa_stream_t *s, int32_t vol[], unsigned int *n) {
-  int status;
-	DWORD volume;
-	WORD left;
-	WORD right;
-
-	ERROR_IF_NO_INIT(s);
-  
-	status = waveOutGetVolume(s->hWaveOut, &volume);
-	HANDLE_WAVE_ERROR(status, "reading audio volume level");
-
-	left = volume & LEFT_CHANNEL_MASK;
-	right = (volume & RIGHT_CHANNEL_MASK) >> 16;
-  vol[0] = (int32_t)(left + right /2);	
-
-	return SA_SUCCESS;
-
-}
-
-/** changes volume as an int in a scale from 0x0000 to 0xFFFF*/
-int sa_stream_change_write_volume(sa_stream_t *s, const int32_t vol[], unsigned int n) {
-  int status;
-	DWORD volume;
-	WORD left;
-	WORD right;
-	
-	ERROR_IF_NO_INIT(s);
-	
-  volume = (DWORD)vol[0];
-	left = volume & LEFT_CHANNEL_MASK;	  
-	right = left;	  
-	volume =  (left << 16) | right;	
-	
-	status = waveOutSetVolume(s->hWaveOut, volume);
-	HANDLE_WAVE_ERROR(status, "setting new audio volume level");	
-
-	return SA_SUCCESS;
-
-
-}
-
-/** sync/timing */
-int sa_stream_get_position(sa_stream_t *s, sa_position_t position, int64_t *pos) {
-	int status;
-  MMTIME  mm;
-
-  ERROR_IF_NO_INIT(s);
-
-  if (position != SA_POSITION_WRITE_HARDWARE) {
-    return SA_ERROR_NOT_SUPPORTED;
-  }
-  // request playback progress in bytes
-  mm.wType = TIME_BYTES;		
-	status = waveOutGetPosition(s->hWaveOut, &mm, sizeof(MMTIME));
-  HANDLE_WAVE_ERROR(status, "reading audio buffer position");
-  *pos = (int64_t)mm.u.cb;
-
-	return SA_SUCCESS;
-}
-
-/* Control/xrun */
-/** Resume playing after a pause */
-int sa_stream_resume(sa_stream_t *s) {
-  int status;  
-  
-  ERROR_IF_NO_INIT(s);
-
-  status = waveOutRestart(s->hWaveOut);
-  HANDLE_WAVE_ERROR(status, "resuming audio playback");
-
-  return SA_SUCCESS;
-}
-/** Pause audio playback (do not empty the buffer) */
-int sa_stream_pause(sa_stream_t *s) {
-  int status;
-
-  ERROR_IF_NO_INIT(s);
-  
-  status = waveOutPause(s->hWaveOut);
-  HANDLE_WAVE_ERROR(status, "resuming audio playback");
-
-  return SA_SUCCESS;
-}
-
-/*
- * -----------------------------------------------------------------------------
- * Private WAVE API specific functions
- * -----------------------------------------------------------------------------
- */
-
-/** 
- * \brief - allocate buffer for writing to system WAVE audio device
- * \param size - size of each audio block
- * \param cound - number of blocks to be allocated
- * \param blocks - pointer to the blocks buffer to be allocated
- * \return - completion status
- */
-int allocateBlocks(int size, int count, WAVEHDR** blocks)
-{
-  unsigned char* buffer;    
-  int i;    
-  WAVEHDR* headers;
-  DWORD totalBufferSize = (size + sizeof(WAVEHDR)) * count;
-    
-  /* allocate memory on heap for the entire set in one go  */    
-  if((buffer = HeapAlloc(
-     GetProcessHeap(), 
-     HEAP_ZERO_MEMORY, 
-     totalBufferSize
-     )) == NULL) {
-      printf("Memory allocation error\n");
-      return SA_ERROR_OOM;
-    }
-
-  /* and set up the pointers to each bit */
-  headers = *blocks = (WAVEHDR*)buffer;
-  buffer += sizeof(WAVEHDR) * count;
-  for(i = 0; i < count; i++) {    
-	  headers[i].dwBufferLength = size;
-    headers[i].lpData = buffer;
-    buffer += size;
-  }
-    
-  return SA_SUCCESS;
-}
-
-/**
- * \brief - free allocated audio buffer
- * \param blocks - pointer to allocated the buffer of audio bloks
- * \return - completion status
- */
-int freeBlocks(WAVEHDR* blocks)
-{    
-  if (blocks == NULL) 
-    return SA_ERROR_INVALID;
-
-  /* and this is why allocateBlocks works the way it does */     
-  HeapFree(GetProcessHeap(), 0, blocks);
-  blocks = NULL;
-
-  return SA_SUCCESS;
-}
-
-/** 
- * \brief - open system default WAVE device
- * \param s - sydney audio stream handle
- * \return - completion status
- */ 
-int openAudio(sa_stream_t *s) {
-  int status;
-  WAVEFORMATEX wfx;    
-  UINT supported = FALSE;
-		  
-  status = allocateBlocks(BLOCK_SIZE, BLOCK_COUNT, &(s->waveBlocks));  
-	HANDLE_WAVE_ERROR(status, "allocating audio buffer blocks");
-  
-  s->waveFreeBlockCount	= BLOCK_COUNT;
-  s->waveCurrentBlock	= 0;  
-  wfx.nSamplesPerSec	= (DWORD)s->rate;	/* sample rate */
-  wfx.wBitsPerSample	= 16;				/* sample size */
-  wfx.nChannels			= s->channels;	/* channels    */
-  wfx.cbSize			= 0;				/* size of _extra_ info */
-  wfx.wFormatTag		= WAVE_FORMAT_PCM;
-  wfx.nBlockAlign		= (wfx.wBitsPerSample * wfx.nChannels) >> 3;
-  wfx.nAvgBytesPerSec	= wfx.nBlockAlign * wfx.nSamplesPerSec;
-
-  supported = waveOutOpen(NULL, WAVE_MAPPER, &wfx, (DWORD_PTR)0, (DWORD_PTR)0, 
-				WAVE_FORMAT_QUERY);
-  if (supported == MMSYSERR_NOERROR) { // audio device opened sucessfully 
-    status = waveOutOpen((LPHWAVEOUT)&(s->hWaveOut), WAVE_MAPPER, &wfx, 
-	  (DWORD_PTR)waveOutProc, (DWORD_PTR)s, CALLBACK_FUNCTION);
-    HANDLE_WAVE_ERROR(status, "opening audio device for playback");
-		printf("Audio device sucessfully opened\n");
-  } 
-  else if (supported == WAVERR_BADFORMAT) {
-    printf("Requested format not supported...\n");
-	  // clean up the memory
-	  freeBlocks(s->waveBlocks);
-    return SA_ERROR_NOT_SUPPORTED;
-  } 
-  else {
-    printf("Error opening default audio device. Exiting...\n");
-	  // clean up the memory
-	  freeBlocks(s->waveBlocks);
-    return SA_ERROR_SYSTEM;
-  }
-  // create notification for data written to a device
-  s->callbackEvent = CreateEvent(0, FALSE, FALSE, 0);
-  // initialise critical section for operations on waveFreeBlockCound variable
-  InitializeCriticalSection(&(s->waveCriticalSection));
-
-  return SA_SUCCESS;
-}
-/**
- * \brief - closes opened audio device handle
- * \param s - sydney audio stream handle
- * \return - completion status
- */
-int closeAudio(sa_stream_t * s) {
-  int status, i;
-  
-  // reseting audio device and flushing buffers
-  status = waveOutReset(s->hWaveOut);    
-  HANDLE_WAVE_ERROR(status, "resetting audio device");
-  
-  /* wait for all blocks to complete */  
-  while(s->waveFreeBlockCount < BLOCK_COUNT)
-	  Sleep(10);
-
-  /* unprepare any blocks that are still prepared */  
-  for(i = 0; i < s->waveFreeBlockCount; i++) {
-    if(s->waveBlocks[i].dwFlags & WHDR_PREPARED) {
-	    status = waveOutUnprepareHeader(s->hWaveOut, &(s->waveBlocks[i]), sizeof(WAVEHDR));
-      HANDLE_WAVE_ERROR(status, "closing audio device");
-    }
-  }    
-
-  freeBlocks(s->waveBlocks);  
-  status = waveOutClose(s->hWaveOut);    
-  HANDLE_WAVE_ERROR(status, "closing audio device");
-
-  DeleteCriticalSection(&(s->waveCriticalSection));
-  CloseHandle(s->callbackEvent);
-  printf("[audio] audio resources cleanup completed\n");
-  
-  return SA_SUCCESS;
-}
-/**
- * \brief - writes PCM audio samples to audio device
- * \param s - valid handle to opened sydney stream
- * \param data - pointer to memory storing audio samples to be played
- * \param nsamples - number of samples in the memory pointed by previous parameter
- * \return - completion status
- */
-int writeAudio(sa_stream_t *s, LPSTR data, int bytes) {    
-  UINT status;
-  WAVEHDR* current;	  
-  int remain;
-
-  current = &(s->waveBlocks[s->waveCurrentBlock]);
-  
-  while(bytes > 0) {
-    /* first make sure the header we're going to use is unprepared */
-    if(current->dwFlags & WHDR_PREPARED) {      
-        status = waveOutUnprepareHeader(s->hWaveOut, current, sizeof(WAVEHDR));         
-        HANDLE_WAVE_ERROR(status, "preparing audio headers for writing");
-    }
-		  
-    if(bytes < (int)(BLOCK_SIZE - current->dwUser)) {							  	    
-		  memcpy(current->lpData + current->dwUser, data, bytes);
-      current->dwUser += bytes;
-      break;
-    }
-	
-    /* remain is even as BLOCK_SIZE and dwUser are even too */
-    remain = BLOCK_SIZE - current->dwUser;      
-  	memcpy(current->lpData + current->dwUser, data, remain);
-    bytes -= remain;
-    data += remain;
-	  current->dwBufferLength = BLOCK_SIZE;
-	  /* write to audio device */
-    waveOutPrepareHeader(s->hWaveOut, current, sizeof(WAVEHDR));
-	  status = waveOutWrite(s->hWaveOut, current, sizeof(WAVEHDR));      
-    HANDLE_WAVE_ERROR(status, "writing audio to audio device");
-      
-    EnterCriticalSection(&(s->waveCriticalSection));
-    s->waveFreeBlockCount--;
-    LeaveCriticalSection(&(s->waveCriticalSection));
-    /*
-     * wait for a block to become free
-     */
-    while (!(s->waveFreeBlockCount)) {
-        //printf("All audio buffer blocks empty\n");        
-      WaitForSingleObject(s->callbackEvent, INFINITE);
-        //Sleep(10);
-    }		  
-		
-    /*
-     * point to the next block
-     */
-    (s->waveCurrentBlock)++;
-    (s->waveCurrentBlock) %= BLOCK_COUNT;		
-
-    current = &(s->waveBlocks[s->waveCurrentBlock]);
-    current->dwUser = 0;
-  }
-  return SA_SUCCESS;
-}
-
-/**
- * \brief - audio callback function called when next WAVE header is played by audio device
- */
-void CALLBACK waveOutProc(
-    HWAVEOUT hWaveOut, 
-    UINT uMsg, 
-    DWORD dwInstance,  
-    DWORD dwParam1,    
-    DWORD dwParam2     
-)
-{
-    /*
-     * pointer to free block counter
-     */
-    sa_stream_t* handle = (sa_stream_t*)dwInstance;
-    /*
-     * ignore calls that occur due to openining and closing the
-     * device.
-     */
-    if(uMsg != WOM_DONE)
-        return;
-
-    EnterCriticalSection(&(handle->waveCriticalSection));
-    (handle->waveFreeBlockCount)++;
-    if ((handle->waveFreeBlockCount) == 1) 
-       SetEvent(handle->callbackEvent);
-    LeaveCriticalSection(&(handle->waveCriticalSection));	
-}
-
-/**
- * \brief - converts frequently reported WAVE error codes to Sydney audio API codes
- */
-int getSAErrorCode(int waveErrorCode) {
-  int error = SA_ERROR_NOT_SUPPORTED;
-
-  switch (waveErrorCode) {
-    case MMSYSERR_NOERROR: 
-      error = SA_SUCCESS;
-      break;
-    case MMSYSERR_ALLOCATED: 
-      error = SA_ERROR_SYSTEM;
-      break;
-    case MMSYSERR_BADDEVICEID:
-      error = SA_ERROR_INVALID;
-      break;
-    case MMSYSERR_NODRIVER:
-      error = SA_ERROR_NO_DRIVER;
-      break;
-    case MMSYSERR_NOTSUPPORTED:
-      error = SA_ERROR_NOT_SUPPORTED;
-      break;          
-    case MMSYSERR_NOMEM: 
-      error = SA_ERROR_OOM;
-      break;
-    case MMSYSERR_INVALHANDLE:
-      error = SA_ERROR_INVALID;
-      break;
-    case WAVERR_BADFORMAT: 
-      error = SA_ERROR_NOT_SUPPORTED;
-      break;
-    case WAVERR_SYNC: 
-      error = SA_ERROR_NOT_SUPPORTED;
-      break;    
-  }
-  return error;
-}
-
-
-/*
- * -----------------------------------------------------------------------------
- * Functions to be implemented next 
- * -----------------------------------------------------------------------------
- */
-
-#define NOT_IMPLEMENTED(func)   func { return SA_ERROR_NOT_SUPPORTED; }
-
-/* "Soft" params */
-NOT_IMPLEMENTED(int sa_stream_set_write_lower_watermark(sa_stream_t *s, size_t size))
-NOT_IMPLEMENTED(int sa_stream_set_read_lower_watermark(sa_stream_t *s, size_t size))
-NOT_IMPLEMENTED(int sa_stream_set_write_upper_watermark(sa_stream_t *s, size_t size))
-NOT_IMPLEMENTED(int sa_stream_set_read_upper_watermark(sa_stream_t *s, size_t size))
-
-/** Set the mapping between channels and the loudspeakers */
-NOT_IMPLEMENTED(int sa_stream_set_channel_map(sa_stream_t *s, const sa_channel_t map[], unsigned int n))
-
-/* Query functions */
-NOT_IMPLEMENTED(int sa_stream_get_mode(sa_stream_t *s, sa_mode_t *access_mode))
-NOT_IMPLEMENTED(int sa_stream_get_pcm_format(sa_stream_t *s, sa_pcm_format_t *format))
-NOT_IMPLEMENTED(int sa_stream_get_rate(sa_stream_t *s, unsigned int *rate))
-NOT_IMPLEMENTED(int sa_stream_get_nchannels(sa_stream_t *s, int *nchannels))
-NOT_IMPLEMENTED(int sa_stream_get_device(sa_stream_t *s, char *device_name, size_t *size))
-NOT_IMPLEMENTED(int sa_stream_get_write_lower_watermark(sa_stream_t *s, size_t *size))
-NOT_IMPLEMENTED(int sa_stream_get_read_lower_watermark(sa_stream_t *s, size_t *size))
-NOT_IMPLEMENTED(int sa_stream_get_write_upper_watermark(sa_stream_t *s, size_t *size))
-NOT_IMPLEMENTED(int sa_stream_get_read_upper_watermark(sa_stream_t *s, size_t *size))
-NOT_IMPLEMENTED(int sa_stream_get_channel_map(sa_stream_t *s, sa_channel_t map[], unsigned int *n))
-
-/*
- * -----------------------------------------------------------------------------
- * Unsupported functions
- * -----------------------------------------------------------------------------
- */
-#define UNSUPPORTED(func)   func { return SA_ERROR_NOT_SUPPORTED; }
-
-/** Create an opaque (e.g. AC3) codec stream */
-UNSUPPORTED(int sa_stream_create_opaque(sa_stream_t **s, const char *client_name, sa_mode_t mode, const char *codec))
-/** Whether xruns cause the card to reset */
-UNSUPPORTED(int sa_stream_set_xrun_mode(sa_stream_t *s, sa_xrun_mode_t mode))
-/** Set the device to non-interleaved mode */
-UNSUPPORTED(int sa_stream_set_non_interleaved(sa_stream_t *s, int enable))
-/** Require dynamic sample rate */
-UNSUPPORTED(int sa_stream_set_dynamic_rate(sa_stream_t *s, int enable))
-/** Select driver */
-UNSUPPORTED(int sa_stream_set_driver(sa_stream_t *s, const char *driver))
-/** Start callback */
-UNSUPPORTED(int sa_stream_start_thread(sa_stream_t *s, sa_event_callback_t callback))
-/** Stop callback */
-UNSUPPORTED(int sa_stream_stop_thread(sa_stream_t *s))
-/** Change the device connected to the stream */
-UNSUPPORTED(int sa_stream_change_device(sa_stream_t *s, const char *device_name))
-/** volume in hundreths of dB*/
-UNSUPPORTED(int sa_stream_change_read_volume(sa_stream_t *s, const int32_t vol[], unsigned int n))
-/** Change the sampling rate */
-UNSUPPORTED(int sa_stream_change_rate(sa_stream_t *s, unsigned int rate))
-/** Change some meta data that is attached to the stream */
-UNSUPPORTED(int sa_stream_change_meta_data(sa_stream_t *s, const char *name, const void *data, size_t size))
-/** Associate opaque user data */
-UNSUPPORTED(int sa_stream_change_user_data(sa_stream_t *s, const void *value))
-/* Hardware-related. This is implementation-specific and hardware specific. */
-UNSUPPORTED(int sa_stream_set_adjust_rate(sa_stream_t *s, sa_adjust_t direction))
-UNSUPPORTED(int sa_stream_set_adjust_nchannels(sa_stream_t *s, sa_adjust_t direction))
-UNSUPPORTED(int sa_stream_set_adjust_pcm_format(sa_stream_t *s, sa_adjust_t direction))
-UNSUPPORTED(int sa_stream_set_adjust_watermarks(sa_stream_t *s, sa_adjust_t direction))
-/* Query functions */
-UNSUPPORTED(int sa_stream_get_codec(sa_stream_t *s, char *codec, size_t *size))
-UNSUPPORTED(int sa_stream_get_user_data(sa_stream_t *s, void **value))
-
-UNSUPPORTED(int sa_stream_get_xrun_mode(sa_stream_t *s, sa_xrun_mode_t *mode))
-UNSUPPORTED(int sa_stream_get_non_interleaved(sa_stream_t *s, int *enabled))
-UNSUPPORTED(int sa_stream_get_dynamic_rate(sa_stream_t *s, int *enabled))
-UNSUPPORTED(int sa_stream_get_driver(sa_stream_t *s, char *driver_name, size_t *size))            
-UNSUPPORTED(int sa_stream_get_read_volume(sa_stream_t *s, int32_t vol[], unsigned int *n))
-UNSUPPORTED(int sa_stream_get_meta_data(sa_stream_t *s, const char *name, void*data, size_t *size))
-UNSUPPORTED(int sa_stream_get_adjust_rate(sa_stream_t *s, sa_adjust_t *direction))
-UNSUPPORTED(int sa_stream_get_adjust_nchannels(sa_stream_t *s, sa_adjust_t *direction))
-UNSUPPORTED(int sa_stream_get_adjust_pcm_format(sa_stream_t *s, sa_adjust_t *direction))
-UNSUPPORTED(int sa_stream_get_adjust_watermarks(sa_stream_t *s, sa_adjust_t *direction))
-/** Get current state of the audio device */
-UNSUPPORTED(int sa_stream_get_state(sa_stream_t *s, sa_state_t *state))
-/** Obtain the error code */
-UNSUPPORTED(int sa_stream_get_event_error(sa_stream_t *s, sa_error_t *error))
-/** Obtain the notification code */
-UNSUPPORTED(int sa_stream_get_event_notify(sa_stream_t *s, sa_notify_t *notify))
-
-/* Blocking IO calls */
-/** Interleaved capture function */
-UNSUPPORTED(int sa_stream_read(sa_stream_t *s, void *data, size_t nbytes))
-/** Non-interleaved capture function */
-UNSUPPORTED(int sa_stream_read_ni(sa_stream_t *s, unsigned int channel, void *data, size_t nbytes))
-
-/** Non-interleaved playback function */
-UNSUPPORTED(int sa_stream_write_ni(sa_stream_t *s, unsigned int channel, const void *data, size_t nbytes))
-/** Interleaved playback function with seek offset */
-UNSUPPORTED(int sa_stream_pwrite(sa_stream_t *s, const void *data, size_t nbytes, int64_t offset, sa_seek_t whence))
-/** Non-interleaved playback function with seek offset */
-UNSUPPORTED(int sa_stream_pwrite_ni(sa_stream_t *s, unsigned int channel, const void *data, size_t nbytes, int64_t offset, sa_seek_t whence))
-
-/** Query how much can be read without blocking */
-UNSUPPORTED(int sa_stream_get_read_size(sa_stream_t *s, size_t *size))
-/** Query how much can be written without blocking */
-UNSUPPORTED(int sa_stream_get_write_size(sa_stream_t *s, size_t *size))
-
-/** Block until all audio has been played */
-UNSUPPORTED(int sa_stream_drain(sa_stream_t *s))
-
-/** Return a human readable error */
-const char *sa_strerror(int code);
deleted file mode 100644
--- a/media/liboggplay_audio/update.sh
+++ /dev/null
@@ -1,5 +0,0 @@
-# Usage: ./update.sh <browser_plugin_src_directory>
-#
-# Copies the needed files from a directory containing the original
-# browser_plugin source that we need for the Mozilla HTML5 media support.
-cp $1/src/audio/* .
new file mode 100644
--- /dev/null
+++ b/media/libsydneyaudio/AUTHORS
@@ -0,0 +1,34 @@
+Jean-Marc Valin (jmspeex) <jean-marc.valin@usherbrooke.ca>
+        - Design
+
+Lennart Poettering  <lennart@poettering.net>
+		- Design
+
+Shane Stephens (shans) <shans@annodex.net>
+        - First Implementation
+
+Chris Double (doublec) <chris.double@double.co.nz>
+		- ALSA support
+		- OSS support
+
+Brian Lu <brian.lu@sun.com>
+		- Sun Audio support
+
+Jeremy D. Lea (reg@openpave.org)
+		- OSS support
+
+Marcin Lubonski <marcin@it.uts.edu.au>
+        - Port to windows
+
+Michael Martin (tahn) <myk.martin@gmail.com>
+        - Port to Max OS X
+		- OSS support
+		- ALSA support
+
+Jan Gerber (j^) <j@oil21.org>
+		- Library creation
+
+Silvia Pfeiffer (ginger) <silvia@annodex.net>
+        - general maintenance
+
+
new file mode 100644
--- /dev/null
+++ b/media/libsydneyaudio/Makefile.in
@@ -0,0 +1,51 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is Mozilla code.
+#
+# The Initial Developer of the Original Code is the Mozilla Corporation.
+# Portions created by the Initial Developer are Copyright (C) 2007
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#  Chris Double <chris.double@double.co.nz>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+DEPTH		= ../..
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+MODULE		= sydneyaudio
+
+DIRS		= \
+		include \
+		src \
+		$(NULL)
+
+include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/media/libsydneyaudio/README_MOZILLA
@@ -0,0 +1,8 @@
+The source from this directory was copied from the libsydneyaudio svn
+source using the update.sh script. The only changes made were those
+applied by update.sh and the addition/upate of Makefile.in files for
+the Mozilla build system.
+
+http://svn.annodex.net/libsydneyaudio/trunk
+
+The svn revision number used was r3730. 
new file mode 100644
--- /dev/null
+++ b/media/libsydneyaudio/include/Makefile.in
@@ -0,0 +1,50 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is Mozilla code.
+#
+# The Initial Developer of the Original Code is the Mozilla Corporation.
+# Portions created by the Initial Developer are Copyright (C) 2007
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#  Chris Double <chris.double@double.co.nz>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+DEPTH		= ../../..
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+MODULE		= sydneyaudio
+
+EXPORTS		= \
+		sydney_audio.h \
+		$(NULL)
+
+include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/media/libsydneyaudio/include/sydney_audio.h
@@ -0,0 +1,461 @@
+#ifndef foosydneyhfoo
+#define foosydneyhfoo
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Initial Developer of the Original Code is
+ * CSIRO
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** *
+ */
+
+/* Requirements:
+
+- In sync mode, the device will automatically write data so that an initial read causes writes
+of zeros to be issued to that one can do "while (1); {read(); write()}
+
+- All functions are thread-safe and can be called in any thread context. None of the functions is
+async-signal safe.
+  
+- It is assumed that duplex streams have a single clock (synchronised)
+*/
+
+#include <sys/types.h>
+#if !defined (WIN32)
+#include <sys/param.h>
+#include <inttypes.h>
+#if defined(__FreeBSD__)
+#include <sys/endian.h>
+#endif
+#else
+#include <stddef.h>
+#endif
+
+/* Detect byte order, based on sys/param.h */
+#undef SA_LITTLE_ENDIAN
+#undef SA_BIG_ENDIAN
+
+#if defined(__BYTE_ORDER)
+#   if __BYTE_ORDER == __LITTLE_ENDIAN
+#       define SA_LITTLE_ENDIAN 1
+#   elif __BYTE_ORDER == __BIG_ENDIAN
+#       define SA_BIG_ENDIAN 1
+#   endif
+#elif defined(_BYTE_ORDER)
+#   if _BYTE_ORDER == _LITTLE_ENDIAN
+#       define SA_LITTLE_ENDIAN 1
+#   elif _BYTE_ORDER == _BIG_ENDIAN
+#       define SA_BIG_ENDIAN 1
+#   endif
+#elif defined(WIN32)
+#   define SA_LITTLE_ENDIAN 1
+#elif defined(__APPLE__)
+#   if defined(__BIG_ENDIAN__)
+#       define SA_BIG_ENDIAN 1
+#   else
+#       define SA_LITTLE_ENDIAN 1
+#   endif
+#elif defined(SOLARIS)
+#   if defined(_BIG_ENDIAN)
+#       define SA_BIG_ENDIAN 1
+#   else
+#       define SA_LITTLE_ENDIAN 1
+#   endif
+#else
+#    error "Cannot determine byte order!"
+#endif
+
+#if defined(WIN32)
+#if !defined(int32_t)
+typedef __int32 int32_t;
+#endif
+#if !defined(int64_t)
+typedef __int64 int64_t;
+#endif
+#endif
+
+typedef struct sa_stream sa_stream_t;
+
+#if defined(WIN32)
+// (left << 16 | right) (16 bits per channel)
+#define SA_VOLUME_MUTED ((int32_t) (0x00000000))
+#else
+/** Volume that corresponds to muted in/out */
+#define SA_VOLUME_MUTED ((int32_t) (-0x80000000))
+#endif
+
+/** Ways to express seek offsets for pread/pwrite */
+typedef enum {
+    SA_SEEK_RELATIVE,
+    SA_SEEK_ABSOLUTE,
+    SA_SEEK_RELATIVE_END,
+    _SA_SEEK_MAX
+} sa_seek_t;
+
+/** Supported formats */
+typedef enum {
+    SA_PCM_FORMAT_U8,
+    SA_PCM_FORMAT_ULAW,
+    SA_PCM_FORMAT_ALAW,
+    SA_PCM_FORMAT_S16_LE,
+    SA_PCM_FORMAT_S16_BE,
+    SA_PCM_FORMAT_S24_LE,
+    SA_PCM_FORMAT_S24_BE,
+    SA_PCM_FORMAT_S32_LE,
+    SA_PCM_FORMAT_S32_BE,
+    SA_PCM_FORMAT_FLOAT32_LE,
+    SA_PCM_FORMAT_FLOAT32_BE,
+    _SA_PCM_FORMAT_MAX
+} sa_pcm_format_t;
+
+/* Native/reverse endianness definitions for PCM */
+#ifdef SA_LITTLE_ENDIAN
+#define SA_PCM_FORMAT_S16_NE SA_PCM_FORMAT_S16_LE
+#define SA_PCM_FORMAT_S24_NE SA_PCM_FORMAT_S24_LE
+#define SA_PCM_FORMAT_S32_NE SA_PCM_FORMAT_S32_LE
+#define SA_PCM_FORMAT_FLOAT32_NE SA_PCM_FORMAT_FLOAT32_LE
+#define SA_PCM_FORMAT_S16_RE SA_PCM_FORMAT_S16_BE
+#define SA_PCM_FORMAT_S24_RE SA_PCM_FORMAT_S24_BE
+#define SA_PCM_FORMAT_S32_RE SA_PCM_FORMAT_S32_BE
+#define SA_PCM_FORMAT_FLOAT32_RE SA_PCM_FORMAT_FLOAT32_BE
+#else
+#define SA_PCM_FORMAT_S16_NE SA_PCM_FORMAT_S16_BE
+#define SA_PCM_FORMAT_S24_NE SA_PCM_FORMAT_S24_BE
+#define SA_PCM_FORMAT_S32_NE SA_PCM_FORMAT_S32_BE
+#define SA_PCM_FORMAT_FLOAT32_NE SA_PCM_FORMAT_FLOAT32_BE
+#define SA_PCM_FORMAT_S16_RE SA_PCM_FORMAT_S16_LE
+#define SA_PCM_FORMAT_S24_RE SA_PCM_FORMAT_S24_LE
+#define SA_PCM_FORMAT_S32_RE SA_PCM_FORMAT_S32_LE
+#define SA_PCM_FORMAT_FLOAT32_RE SA_PCM_FORMAT_FLOAT32_LE
+#endif
+
+#define SA_CODEC_MPEG "mpeg"
+#define SA_CODEC_AC3 "ac3"
+#define SA_CODEC_GSM "gsm"
+#define SA_CODEC_VORBIS "vorbis"
+#define SA_CODEC_SPEEX "speex"
+
+/** Device opening modes */
+typedef enum {
+    SA_MODE_WRONLY = 1,
+    SA_MODE_RDONLY = 2,
+    SA_MODE_RDWR   = 3,
+    _SA_MODE_MAX   = 4
+} sa_mode_t;
+
+/** Error codes */
+typedef enum {
+    SA_SUCCESS = 0,
+    SA_ERROR_NOT_SUPPORTED = -1,
+    SA_ERROR_INVALID = -2,
+    SA_ERROR_STATE = -3,
+    SA_ERROR_OOM = -4,
+    SA_ERROR_NO_DEVICE = -5,
+    SA_ERROR_NO_DRIVER = -6,
+    SA_ERROR_NO_CODEC = -7,
+    SA_ERROR_NO_PCM_FORMAT = -7,
+    SA_ERROR_SYSTEM = -8,
+    SA_ERROR_NO_INIT = -9,
+    SA_ERROR_NO_META = -10,
+    SA_ERROR_NO_DATA = -11,
+    SA_ERROR_NO_SPACE = -12,
+    _SA_ERROR_MAX = -13
+} sa_error_t;
+
+/** Possible events for notifications */
+typedef enum {
+    SA_NOTIFY_REQUEST_START,
+    SA_NOTIFY_REQUEST_STOP,
+    SA_NOTIFY_CHANGED_READ_VOLUME,
+    SA_NOTIFY_CHANGED_WRITE_VOLUME,
+    SA_NOTIFY_CHANGED_DEVICE,
+    _SA_NOTIFY_MAX
+} sa_notify_t;
+
+/** Classes of events */
+typedef enum {
+    SA_EVENT_REQUEST_IO,
+    SA_EVENT_INIT_THREAD,
+    SA_EVENT_NOTIFY,
+    SA_EVENT_ERROR,
+    _SA_EVENT_MAX
+} sa_event_t;
+
+/** List of sample position queries */
+typedef enum {
+    SA_POSITION_WRITE_DELAY,
+    SA_POSITION_WRITE_HARDWARE,
+    SA_POSITION_WRITE_SOFTWARE,
+    SA_POSITION_READ_DELAY,
+    SA_POSITION_READ_HARDWARE,
+    SA_POSITION_READ_SOFTWARE,
+    SA_POSITION_DUPLEX_DELAY,
+    _SA_POSITION_MAX
+} sa_position_t;
+
+/* Channel positions */
+typedef enum {
+    SA_CHANNEL_MONO,
+    SA_CHANNEL_LEFT,
+    SA_CHANNEL_RIGHT,
+    SA_CHANNEL_CENTER,
+    SA_CHANNEL_FRONT_LEFT,
+    SA_CHANNEL_FRONT_RIGHT,
+    SA_CHANNEL_FRONT_CENTER,
+    SA_CHANNEL_REAR_LEFT,
+    SA_CHANNEL_REAR_RIGHT,
+    SA_CHANNEL_REAR_CENTER,
+    SA_CHANNEL_LFE,
+    SA_CHANNEL_FRONT_LEFT_OF_CENTER,
+    SA_CHANNEL_FRONT_RIGHT_OF_CENTER,
+    SA_CHANNEL_SIDE_LEFT,
+    SA_CHANNEL_SIDE_RIGHT,
+    SA_CHANNEL_TOP_CENTER,
+    SA_CHANNEL_TOP_FRONT_LEFT,
+    SA_CHANNEL_TOP_FRONT_RIGHT,
+    SA_CHANNEL_TOP_FRONT_CENTER,
+    SA_CHANNEL_TOP_REAR_LEFT,
+    SA_CHANNEL_TOP_REAR_RIGHT,
+    SA_CHANNEL_TOP_REAR_CENTER,
+    SA_CHANNEL_AUX0,
+    SA_CHANNEL_AUX1,
+    SA_CHANNEL_AUX2,
+    SA_CHANNEL_AUX3,
+    SA_CHANNEL_AUX4,
+    SA_CHANNEL_AUX5,
+    SA_CHANNEL_AUX6,
+    SA_CHANNEL_AUX7,
+    SA_CHANNEL_AUX8,
+    SA_CHANNEL_AUX9,
+    SA_CHANNEL_AUX10,
+    SA_CHANNEL_AUX11,
+    SA_CHANNEL_AUX12,
+    SA_CHANNEL_AUX13,
+    SA_CHANNEL_AUX14,
+    SA_CHANNEL_AUX15,
+    SA_CHANNEL_AUX16,
+    SA_CHANNEL_AUX17,
+    SA_CHANNEL_AUX18,
+    SA_CHANNEL_AUX19,
+    SA_CHANNEL_AUX20,
+    SA_CHANNEL_AUX21,
+    SA_CHANNEL_AUX22,
+    SA_CHANNEL_AUX23,
+    SA_CHANNEL_AUX24,
+    SA_CHANNEL_AUX25,
+    SA_CHANNEL_AUX26,
+    SA_CHANNEL_AUX27,
+    SA_CHANNEL_AUX28,
+    SA_CHANNEL_AUX29,
+    SA_CHANNEL_AUX30,
+    SA_CHANNEL_AUX31,
+    _SA_CHANNEL_MAX
+} sa_channel_t;
+
+typedef enum {
+    SA_STATE_INIT,
+    SA_STATE_RUNNING,
+    SA_STATE_STOPPED,
+    /* put more stuff */
+    _SA_STATE_MAX
+} sa_state_t;
+
+typedef enum {
+    SA_XRUN_MODE_STOP,
+    SA_XRUN_MODE_SPIN,
+    _SA_XRUN_MODE_MAX
+} sa_xrun_mode_t;
+
+typedef enum {
+    SA_ADJUST_UP = 1,
+    SA_ADJUST_DOWN = -1,
+    SA_ADJUST_NONE = 0
+} sa_adjust_t;
+
+/* Some kind of meta information.  */
+#define SA_META_CLIENT_NAME "sydney.client-name"     /* utf-8 */ 
+#define SA_META_PROCESS_ID "sydney.process-id"       /* getpid() */
+#define SA_META_LANGUAGE "sydney.language"           /* de_DE and similar */
+
+/* Some kind of meta information. Not filled in */
+#define SA_META_STREAM_NAME "sydney.stream-name"     /* utf-8 */ 
+#define SA_META_ICON_NAME "sydney.icon-name"         /* file name (no slashes) */
+#define SA_META_ICON_PNG "sydney.icon-png"           /* PNG blob */
+#define SA_META_ROLE "sydney.role"                   /* one of: "music", "phone", "game", "event" */
+#define SA_META_X11_DISPLAY "sydney.x11-display"     /* X11 display */
+#define SA_META_X11_WINDOW "sydney.x11-window"       /* X11 window id */
+
+/** Main callback function */
+typedef int (*sa_event_callback_t)(sa_stream_t *s, sa_event_t event);
+
+/** Create an opaque (e.g. AC3) codec stream */
+int sa_stream_create_opaque(sa_stream_t **s, const char *client_name, sa_mode_t mode, const char *codec);
+
+/** Normal way to open a PCM device */
+int sa_stream_create_pcm(sa_stream_t **s, const char *client_name, sa_mode_t mode, sa_pcm_format_t format, unsigned int rate, unsigned int nchannels);
+
+/** Initialise the device */
+int sa_stream_open(sa_stream_t *s);
+
+/** Close/destroy everything */
+int sa_stream_destroy(sa_stream_t *s);
+
+/* "Soft" params */
+int sa_stream_set_write_lower_watermark(sa_stream_t *s, size_t size);
+int sa_stream_set_read_lower_watermark(sa_stream_t *s, size_t size);
+int sa_stream_set_write_upper_watermark(sa_stream_t *s, size_t size);
+int sa_stream_set_read_upper_watermark(sa_stream_t *s, size_t size);
+
+/** Set the mapping between channels and the loudspeakers */
+int sa_stream_set_channel_map(sa_stream_t *s, const sa_channel_t map[], unsigned int n);
+
+/** Whether xruns cause the card to reset */
+int sa_stream_set_xrun_mode(sa_stream_t *s, sa_xrun_mode_t mode);
+
+/** Set the device to non-interleaved mode */
+int sa_stream_set_non_interleaved(sa_stream_t *s, int enable);
+
+/** Require dynamic sample rate */
+int sa_stream_set_dynamic_rate(sa_stream_t *s, int enable);
+
+/** Select driver */
+int sa_stream_set_driver(sa_stream_t *s, const char *driver);
+
+/** Start callback */
+int sa_stream_start_thread(sa_stream_t *s, sa_event_callback_t callback);
+
+/** Start callback */
+int sa_stream_stop_thread(sa_stream_t *s);
+
+/** Change the device connected to the stream */
+int sa_stream_change_device(sa_stream_t *s, const char *device_name);
+
+/** volume in hundreths of dB*/
+int sa_stream_change_read_volume(sa_stream_t *s, const int32_t vol[], unsigned int n);
+
+/** volume in hundreths of dB*/
+int sa_stream_change_write_volume(sa_stream_t *s, const int32_t vol[], unsigned int n);
+
+/** Change the sampling rate */
+int sa_stream_change_rate(sa_stream_t *s, unsigned int rate);
+
+/** Change some meta data that is attached to the stream */
+int sa_stream_change_meta_data(sa_stream_t *s, const char *name, const void *data, size_t size);
+
+/** Associate opaque user data */
+int sa_stream_change_user_data(sa_stream_t *s, const void *value);
+
+/* Hardware-related. This is implementation-specific and hardware specific. */
+int sa_stream_set_adjust_rate(sa_stream_t *s, sa_adjust_t direction);
+int sa_stream_set_adjust_nchannels(sa_stream_t *s, sa_adjust_t direction);
+int sa_stream_set_adjust_pcm_format(sa_stream_t *s, sa_adjust_t direction);
+int sa_stream_set_adjust_watermarks(sa_stream_t *s, sa_adjust_t direction);
+
+/* Query functions */
+
+int sa_stream_get_mode(sa_stream_t *s, sa_mode_t *access_mode);
+int sa_stream_get_codec(sa_stream_t *s, char *codec, size_t *size);
+int sa_stream_get_pcm_format(sa_stream_t *s, sa_pcm_format_t *format);
+int sa_stream_get_rate(sa_stream_t *s, unsigned int *rate);
+int sa_stream_get_nchannels(sa_stream_t *s, int *nchannels);
+int sa_stream_get_user_data(sa_stream_t *s, void **value);
+int sa_stream_get_write_lower_watermark(sa_stream_t *s, size_t *size);
+int sa_stream_get_read_lower_watermark(sa_stream_t *s, size_t *size);
+int sa_stream_get_write_upper_watermark(sa_stream_t *s, size_t *size);
+int sa_stream_get_read_upper_watermark(sa_stream_t *s, size_t *size);
+int sa_stream_get_channel_map(sa_stream_t *s, sa_channel_t map[], unsigned int *n);
+int sa_stream_get_xrun_mode(sa_stream_t *s, sa_xrun_mode_t *mode);
+int sa_stream_get_non_interleaved(sa_stream_t *s, int *enabled);
+int sa_stream_get_dynamic_rate(sa_stream_t *s, int *enabled);
+int sa_stream_get_driver(sa_stream_t *s, char *driver_name, size_t *size);
+int sa_stream_get_device(sa_stream_t *s, char *device_name, size_t *size);
+int sa_stream_get_read_volume(sa_stream_t *s, int32_t vol[], unsigned int *n);
+int sa_stream_get_write_volume(sa_stream_t *s, int32_t vol[], unsigned int *n);
+int sa_stream_get_meta_data(sa_stream_t *s, const char *name, void*data, size_t *size);
+int sa_stream_get_adjust_rate(sa_stream_t *s, sa_adjust_t *direction);
+int sa_stream_get_adjust_nchannels(sa_stream_t *s, sa_adjust_t *direction);
+int sa_stream_get_adjust_pcm_format(sa_stream_t *s, sa_adjust_t *direction);
+int sa_stream_get_adjust_watermarks(sa_stream_t *s, sa_adjust_t *direction);
+
+/** Get current state of the audio device */
+int sa_stream_get_state(sa_stream_t *s, sa_state_t *state);
+
+/** Obtain the error code */
+int sa_stream_get_event_error(sa_stream_t *s, sa_error_t *error);
+
+/** Obtain the notification code */
+int sa_stream_get_event_notify(sa_stream_t *s, sa_notify_t *notify);
+
+/** sync/timing */
+int sa_stream_get_position(sa_stream_t *s, sa_position_t position, int64_t *pos);
+
+
+/* Blocking IO calls */
+
+/** Interleaved capture function */
+int sa_stream_read(sa_stream_t *s, void *data, size_t nbytes);
+/** Non-interleaved capture function */
+int sa_stream_read_ni(sa_stream_t *s, unsigned int channel, void *data, size_t nbytes);
+
+/** Interleaved playback function */
+int sa_stream_write(sa_stream_t *s, const void *data, size_t nbytes);
+/** Non-interleaved playback function */
+int sa_stream_write_ni(sa_stream_t *s, unsigned int channel, const void *data, size_t nbytes);
+/** Interleaved playback function with seek offset */
+int sa_stream_pwrite(sa_stream_t *s, const void *data, size_t nbytes, int64_t offset, sa_seek_t whence);
+/** Non-interleaved playback function with seek offset */
+int sa_stream_pwrite_ni(sa_stream_t *s, unsigned int channel, const void *data, size_t nbytes, int64_t offset, sa_seek_t whence);
+
+
+/** Query how much can be read without blocking */
+int sa_stream_get_read_size(sa_stream_t *s, size_t *size);
+/** Query how much can be written without blocking */
+int sa_stream_get_write_size(sa_stream_t *s, size_t *size);
+
+
+/* Control/xrun */
+
+/** Resume playing after a pause */
+int sa_stream_resume(sa_stream_t *s);
+
+/** Pause audio playback (do not empty the buffer) */
+int sa_stream_pause(sa_stream_t *s);
+
+/** Block until all audio has been played */
+int sa_stream_drain(sa_stream_t *s);
+
+/** Return a human readable error */
+const char *sa_strerror(int code);
+
+/* Extensions */
+int
+sa_stream_set_volume_abs(sa_stream_t *s, float vol);
+
+int
+sa_stream_get_volume_abs(sa_stream_t *s, float *vol);
+
+#endif
new file mode 100644
--- /dev/null
+++ b/media/libsydneyaudio/src/Makefile.in
@@ -0,0 +1,78 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is Mozilla code.
+#
+# The Initial Developer of the Original Code is the Mozilla Corporation.
+# Portions created by the Initial Developer are Copyright (C) 2007
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#  Chris Double <chris.double@double.co.nz>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+DEPTH		= ../../..
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+MODULE		= sydneyaudio
+LIBRARY_NAME	= sydneyaudio
+FORCE_STATIC_LIB= 1
+
+ifeq ($(OS_ARCH),Linux)
+CSRCS		= \
+		sydney_audio_alsa.c \
+		$(NULL)
+endif
+
+ifneq (,$(filter WINNT WINCE,$(OS_ARCH)))
+CSRCS		= \
+		sydney_audio_waveapi.c \
+		$(NULL)
+endif
+
+ifeq ($(OS_ARCH),Darwin)
+CSRCS		= \
+		sydney_audio_mac.c \
+		$(NULL)
+
+OS_LIBS += -framework CoreAudio -framework AudioToolbox -framework AudioUnit -framework Carbon
+endif
+
+ifeq ($(OS_ARCH),SunOS)
+CSRCS		= \
+		sydney_audio_sunaudio.c \
+		$(NULL)
+endif
+
+ifeq ($(OS_ARCH),WINNT)
+OS_LIBS += winmm.lib
+endif
+
+include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/media/libsydneyaudio/src/sydney_audio_alsa.c
@@ -0,0 +1,734 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Initial Developer of the Original Code is
+ * CSIRO
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s): Michael Martin
+ *                 Chris Double (chris.double@double.co.nz)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** *
+ */
+#include <stdlib.h>
+#include <pthread.h>
+#include <alsa/asoundlib.h>
+#include "sydney_audio.h"
+
+/* ALSA implementation based heavily on sydney_audio_mac.c */
+
+/*
+ * The audio interface is based on a "pull" I/O model, which means you
+ * can't just provide a data buffer and tell the audio device to play; you must
+ * register a callback and provide data as the device asks for it. To support
+ * sydney audio's "write-to-play" style interface, we have to buffer up the
+ * data as it arrives and feed it to the callback as required.
+ *
+ * This is handled by a simple linked list of buffers; data is always written
+ * to the tail and read from the head. Each buffer tracks the start and end
+ * positions of its contained data. Buffers are allocated when the tail buffer
+ * fills, and freed when the head buffer empties. There is always at least one
+ * buffer allocated.
+ *
+ *       s   e      s      e      s  e            + data read
+ *    +++#####  ->  ########  ->  ####----        # data written
+ *    ^                           ^               - empty
+ *    bl_head                     bl_tail
+ */
+
+typedef struct sa_buf sa_buf;
+struct sa_buf {
+  unsigned int      size;
+  unsigned int      start;
+  unsigned int      end;
+  sa_buf          * next;
+  unsigned char     data[0];
+};
+
+struct sa_stream {
+  snd_pcm_t*        output_unit;
+  pthread_t         thread_id;
+  pthread_mutex_t   mutex;
+  char              playing;
+  int64_t           bytes_played;
+
+  /* audio format info */
+  unsigned int      rate;
+  unsigned int      n_channels;
+  unsigned int      bytes_per_ch;
+
+  /* buffer list */
+  sa_buf          * bl_head;
+  sa_buf          * bl_tail;
+  int               n_bufs;
+};
+
+
+/*
+ * Use a default buffer size with enough room for one second of audio,
+ * assuming stereo data at 44.1kHz with 32 bits per channel, and impose
+ * a generous limit on the number of buffers.
+ */
+#define BUF_SIZE    (2 * 44100 * 4)
+#define BUF_LIMIT   5
+
+#if BUF_LIMIT < 2
+#error BUF_LIMIT must be at least 2!
+#endif
+
+static void audio_callback(void* s);
+static sa_buf *new_buffer(void);
+
+
+/*
+ * -----------------------------------------------------------------------------
+ * Startup and shutdown functions
+ * -----------------------------------------------------------------------------
+ */
+
+int
+sa_stream_create_pcm(
+  sa_stream_t      ** _s,
+  const char        * client_name,
+  sa_mode_t           mode,
+  sa_pcm_format_t     format,
+  unsigned  int       rate,
+  unsigned  int       n_channels
+) {
+  sa_stream_t   * s = 0;
+
+  /*
+   * Make sure we return a NULL stream pointer on failure.
+   */
+  if (_s == NULL) {
+    return SA_ERROR_INVALID;
+  }
+  *_s = NULL;
+
+  if (mode != SA_MODE_WRONLY) {
+    return SA_ERROR_NOT_SUPPORTED;
+  }
+  if (format != SA_PCM_FORMAT_S16_LE) {
+    return SA_ERROR_NOT_SUPPORTED;
+  }
+
+  /*
+   * Allocate the instance and required resources.
+   */
+  if ((s = malloc(sizeof(sa_stream_t))) == NULL) {
+    return SA_ERROR_OOM;
+  }
+  if ((s->bl_head = new_buffer()) == NULL) {
+    free(s);
+    return SA_ERROR_OOM;
+  }
+  if (pthread_mutex_init(&s->mutex, NULL) != 0) {
+    free(s->bl_head);
+    free(s);
+    return SA_ERROR_SYSTEM;
+  }
+
+  s->output_unit  = NULL;
+  s->thread_id    = 0;
+  s->playing      = 0;
+  s->bytes_played = 0;
+  s->rate         = rate;
+  s->n_channels   = n_channels;
+  s->bytes_per_ch = 2;
+  s->bl_tail      = s->bl_head;
+  s->n_bufs       = 1;
+
+  *_s = s;
+  return SA_SUCCESS;
+}
+
+
+int
+sa_stream_open(sa_stream_t *s) {
+
+  if (s == NULL) {
+    return SA_ERROR_NO_INIT;
+  }
+  if (s->output_unit != NULL) {
+    return SA_ERROR_INVALID;
+  }
+
+  if (snd_pcm_open(&s->output_unit, 
+                   "default", 
+                   SND_PCM_STREAM_PLAYBACK, 
+                   0) < 0) {
+    return SA_ERROR_NO_DEVICE;
+  }
+  
+  if (snd_pcm_set_params(s->output_unit,
+                         SND_PCM_FORMAT_S16_LE,
+                         SND_PCM_ACCESS_RW_INTERLEAVED,
+                         s->n_channels,
+                         s->rate,
+                         1,
+                         0) < 0) {
+    snd_pcm_close(s->output_unit);
+    s->output_unit = NULL;
+    return SA_ERROR_NOT_SUPPORTED;
+  }
+
+  return SA_SUCCESS;
+}
+
+
+int
+sa_stream_destroy(sa_stream_t *s) {
+  int result = SA_SUCCESS;
+
+  if (s == NULL) {
+    return SA_SUCCESS;
+  }
+
+  pthread_mutex_lock(&s->mutex);
+
+  /*
+   * This causes the thread sending data to ALSA to stop
+   */
+  s->thread_id = 0;
+
+  /*
+   * Shut down the audio output device.
+   */
+  if (s->output_unit != NULL) {
+    if (s->playing && snd_pcm_close(s->output_unit) < 0) {
+      result = SA_ERROR_SYSTEM;
+    }
+  }
+
+  pthread_mutex_unlock(&s->mutex);
+
+  /*
+   * Release resources.
+   */
+  if (pthread_mutex_destroy(&s->mutex) != 0) {
+    result = SA_ERROR_SYSTEM;
+  }
+  while (s->bl_head != NULL) {
+    sa_buf  * next = s->bl_head->next;
+    free(s->bl_head);
+    s->bl_head = next;
+  }
+  free(s);
+
+  return result;
+}
+
+
+
+/*
+ * -----------------------------------------------------------------------------
+ * Data read and write functions
+ * -----------------------------------------------------------------------------
+ */
+
+int
+sa_stream_write(sa_stream_t *s, const void *data, size_t nbytes) {
+  int result = SA_SUCCESS;
+
+  if (s == NULL || s->output_unit == NULL) {
+    return SA_ERROR_NO_INIT;
+  }
+  if (nbytes == 0) {
+    return SA_SUCCESS;
+  }
+
+  pthread_mutex_lock(&s->mutex);
+
+  /*
+   * Append the new data to the end of our buffer list.
+   */
+  while (1) {
+    unsigned int avail = s->bl_tail->size - s->bl_tail->end;
+
+    if (nbytes <= avail) {
+
+      /*
+       * The new data will fit into the current tail buffer, so
+       * just copy it in and we're done.
+       */
+      memcpy(s->bl_tail->data + s->bl_tail->end, data, nbytes);
+      s->bl_tail->end += nbytes;
+      break;
+
+    } else {
+
+      /*
+       * Copy what we can into the tail and allocate a new buffer
+       * for the rest.
+       */
+      memcpy(s->bl_tail->data + s->bl_tail->end, data, avail);
+      s->bl_tail->end += avail;
+      data = ((unsigned char *)data) + avail;
+      nbytes -= avail;
+
+      /* 
+       * If we still have data left to copy but we've hit the limit of
+       * allowable buffer allocations, we need to spin for a bit to allow
+       * the audio callback function to slurp some more data up.
+       */
+      if (nbytes > 0 && s->n_bufs == BUF_LIMIT) {
+#ifdef TIMING_TRACE
+        printf("#");  /* too much audio data */
+#endif
+        if (!s->playing) {
+          /*
+           * We haven't even started playing yet! That means the
+           * BUF_SIZE/BUF_LIMIT values are too low... Not much we can
+           * do here; spinning won't help because the audio callback
+           * hasn't been enabled yet. Oh well, error time.
+           */
+          printf("Too much audio data received before audio device enabled!\n");
+          result = SA_ERROR_SYSTEM;
+          break;
+        }
+        while (s->n_bufs == BUF_LIMIT) {
+          struct timespec ts = {0, 1000000};
+          pthread_mutex_unlock(&s->mutex);
+          nanosleep(&ts, NULL);
+          pthread_mutex_lock(&s->mutex);
+        }
+      }
+
+      /* 
+       * Allocate a new tail buffer, and go 'round again to fill it up.
+       */
+      if ((s->bl_tail->next = new_buffer()) == NULL) {
+        result = SA_ERROR_OOM;
+        break;
+      }
+      s->n_bufs++;
+      s->bl_tail = s->bl_tail->next;
+    
+    } /* if (nbytes <= avail), else */
+
+  } /* while (1) */
+
+  pthread_mutex_unlock(&s->mutex);
+
+  /*
+   * Once we have our first block of audio data, enable the audio callback
+   * function. This doesn't need to be protected by the mutex, because
+   * s->playing is not used in the audio callback thread, and it's probably
+   * better not to be inside the lock when we enable the audio callback.
+   */
+  if (!s->playing) {
+    s->playing = 1;
+    if (pthread_create(&s->thread_id, NULL, (void *)audio_callback, s) != 0) {
+      result = SA_ERROR_SYSTEM;
+    }
+  }
+
+  return result;
+}
+
+
+static void audio_callback(void* data)
+{
+  sa_stream_t* s = (sa_stream_t*)data;
+  snd_pcm_uframes_t buffer_size;
+  snd_pcm_uframes_t period_size;
+  unsigned int bytes_per_frame = s->n_channels * s->bytes_per_ch;
+  char* buffer = 0;
+
+#ifdef TIMING_TRACE
+  printf(".");  /* audio read 'tick' */
+#endif
+
+  snd_pcm_get_params(s->output_unit, &buffer_size, &period_size);
+ 
+  buffer = malloc(period_size * bytes_per_frame);
+ 
+  while(1) {
+    char* dst = buffer;
+    unsigned int bytes_to_copy   = period_size * bytes_per_frame;
+    snd_pcm_sframes_t frames;
+
+    pthread_mutex_lock(&s->mutex);
+    if (!s->thread_id)
+      break;
+
+    /*
+     * Consume data from the start of the buffer list.
+     */
+    while (1) {
+      unsigned int avail = s->bl_head->end - s->bl_head->start;
+      assert(s->bl_head->start <= s->bl_head->end);
+
+      if (avail >= bytes_to_copy) {
+        /*
+         * We have all we need in the head buffer, so just grab it and go.
+         */
+        memcpy(dst, s->bl_head->data + s->bl_head->start, bytes_to_copy);
+        s->bl_head->start += bytes_to_copy;
+        s->bytes_played += bytes_to_copy;
+        break;
+    
+      } else {
+        sa_buf* next = 0;
+        /*
+         * Copy what we can from the head and move on to the next buffer.
+         */
+        memcpy(dst, s->bl_head->data + s->bl_head->start, avail);
+        s->bl_head->start += avail;
+        dst += avail;
+        bytes_to_copy -= avail;
+        s->bytes_played += avail;
+
+        /*
+         * We want to free the now-empty buffer, but not if it's also the
+         * current tail. If it is the tail, we don't have enough data to fill
+         * the destination buffer, so we'll just zero it out and give up.
+         */
+        next = s->bl_head->next;
+        if (next == NULL) {
+#ifdef TIMING_TRACE
+          printf("!");  /* not enough audio data */
+#endif
+          memset(dst, 0, bytes_to_copy);
+          break;
+        }
+        free(s->bl_head);
+        s->bl_head = next;
+        s->n_bufs--;
+    
+      } /* if (avail >= bytes_to_copy), else */
+      
+    } /* while (1) */
+    
+    pthread_mutex_unlock(&s->mutex);
+    
+    frames = snd_pcm_writei(s->output_unit, buffer, period_size);
+    if (frames < 0) {
+      frames = snd_pcm_recover(s->output_unit, frames, 1);
+      if (frames < 0) {
+        printf("snc_pcm_recover error: %s\n", snd_strerror(frames));
+      }
+      if(frames > 0 && frames < period_size)
+        printf("short write (expected %d, wrote %d)\n", (int)period_size, (int)frames);;
+    }
+  }
+  free(buffer);
+}
+
+
+
+/*
+ * -----------------------------------------------------------------------------
+ * General query and support functions
+ * -----------------------------------------------------------------------------
+ */
+
+int
+sa_stream_get_write_size(sa_stream_t *s, size_t *size) {
+  sa_buf  * b;
+  size_t    used = 0;
+
+  if (s == NULL || s->output_unit == NULL) {
+    return SA_ERROR_NO_INIT;
+  }
+
+  pthread_mutex_lock(&s->mutex);
+
+  /*
+   * The sum of the free space in the tail buffer plus the size of any new
+   * buffers represents the write space available before blocking.
+   */
+  unsigned int avail = s->bl_tail->size - s->bl_tail->end;
+  avail += (BUF_LIMIT - s->n_bufs) * BUF_SIZE;
+  *size = avail;
+
+  pthread_mutex_unlock(&s->mutex);
+  return SA_SUCCESS;
+}
+
+
+int
+sa_stream_get_position(sa_stream_t *s, sa_position_t position, int64_t *pos) {
+
+  if (s == NULL || s->output_unit == NULL) {
+    return SA_ERROR_NO_INIT;
+  }
+  if (position != SA_POSITION_WRITE_SOFTWARE) {
+    return SA_ERROR_NOT_SUPPORTED;
+  }
+
+  pthread_mutex_lock(&s->mutex);
+  *pos = s->bytes_played;
+  pthread_mutex_unlock(&s->mutex);
+  return SA_SUCCESS;
+}
+
+
+int
+sa_stream_pause(sa_stream_t *s) {
+
+  if (s == NULL || s->output_unit == NULL) {
+    return SA_ERROR_NO_INIT;
+  }
+
+  pthread_mutex_lock(&s->mutex);
+#if 0 /* TODO */
+  AudioOutputUnitStop(s->output_unit);
+#endif
+  pthread_mutex_unlock(&s->mutex);
+  return SA_SUCCESS;
+}
+
+
+int
+sa_stream_resume(sa_stream_t *s) {
+
+  if (s == NULL || s->output_unit == NULL) {
+    return SA_ERROR_NO_INIT;
+  }
+
+  pthread_mutex_lock(&s->mutex);
+
+  /*
+   * The audio device resets its mSampleTime counter after pausing,
+   * so we need to clear our tracking value to keep that in sync.
+   */
+  s->bytes_played = 0;
+#if 0 /* TODO */
+  AudioOutputUnitStart(s->output_unit);
+#endif
+  pthread_mutex_unlock(&s->mutex);
+  return SA_SUCCESS;
+}
+
+
+static sa_buf *
+new_buffer(void) {
+  sa_buf  * b = malloc(sizeof(sa_buf) + BUF_SIZE);
+  if (b != NULL) {
+    b->size  = BUF_SIZE;
+    b->start = 0;
+    b->end   = 0;
+    b->next  = NULL;
+  }
+  return b;
+}
+
+
+int
+sa_stream_drain(sa_stream_t *s)
+{
+  if (s == NULL || s->output_unit == NULL) {
+    return SA_ERROR_NO_INIT;
+  }
+
+  while (1) {
+    pthread_mutex_lock(&s->mutex);
+    sa_buf  * b;
+    size_t    used = 0;
+    for (b = s->bl_head; b != NULL; b = b->next) {
+      used += b->end - b->start;
+    }
+    pthread_mutex_unlock(&s->mutex);
+
+    if (used == 0) {
+      break;
+    }
+
+    struct timespec ts = {0, 1000000};
+    nanosleep(&ts, NULL);
+  }
+  return SA_SUCCESS;
+}
+
+
+
+/*
+ * -----------------------------------------------------------------------------
+ * Extension functions
+ * -----------------------------------------------------------------------------
+ */
+
+int
+sa_stream_set_volume_abs(sa_stream_t *s, float vol) {
+  snd_mixer_t* mixer = 0;
+  snd_mixer_elem_t* elem = 0;
+  if (s == NULL || s->output_unit == NULL) {
+    return SA_ERROR_NO_INIT;
+  }
+
+  if (snd_mixer_open(&mixer, 0) < 0) {
+    return SA_ERROR_SYSTEM;
+  }
+
+  if (snd_mixer_attach(mixer, "default") < 0) {
+    snd_mixer_close(mixer);
+    return SA_ERROR_SYSTEM;
+  }
+
+  if (snd_mixer_selem_register(mixer, NULL, NULL) < 0) {
+    snd_mixer_close(mixer);
+    return SA_ERROR_SYSTEM;
+  }
+
+  if (snd_mixer_load(mixer) < 0) {
+    snd_mixer_close(mixer);
+    return SA_ERROR_SYSTEM;
+  }
+
+#if 0
+  snd_mixer_elem_t* elem = 0;
+  for (elem = snd_mixer_first_elem(mixer); elem != NULL; elem = snd_mixer_elem_next(elem)) {
+    if (snd_mixer_selem_has_playback_volume(elem)) {
+      printf("Playback %s\n", snd_mixer_selem_get_name(elem));
+    }
+    else {
+      printf("No Playback: %s\n", snd_mixer_selem_get_name(elem));
+    }
+  }
+#endif
+  elem = snd_mixer_first_elem(mixer);
+  if (elem && snd_mixer_selem_has_playback_volume(elem)) {
+    long min = 0;
+    long max = 0;
+    if (snd_mixer_selem_get_playback_volume_range(elem, &min, &max) >= 0) {
+      snd_mixer_selem_set_playback_volume_all(elem, (max-min)*vol + min);
+    } 
+  }
+  snd_mixer_close(mixer);
+
+  return SA_SUCCESS;
+}
+
+
+int
+sa_stream_get_volume_abs(sa_stream_t *s, float *vol) {
+  snd_mixer_t* mixer = 0;
+  snd_mixer_elem_t* elem = 0;
+  long value = 0;
+
+  if (s == NULL || s->output_unit == NULL) {
+    return SA_ERROR_NO_INIT;
+  }
+
+  if (snd_mixer_open(&mixer, 0) < 0) {
+    return SA_ERROR_SYSTEM;
+  }
+
+  if (snd_mixer_attach(mixer, "default") < 0) {
+    snd_mixer_close(mixer);
+    return SA_ERROR_SYSTEM;
+  }
+
+  if (snd_mixer_selem_register(mixer, NULL, NULL) < 0) {
+    snd_mixer_close(mixer);
+    return SA_ERROR_SYSTEM;
+  }
+
+  if (snd_mixer_load(mixer) < 0) {
+    snd_mixer_close(mixer);
+    return SA_ERROR_SYSTEM;
+  }
+
+  elem = snd_mixer_first_elem(mixer);
+  if (elem && snd_mixer_selem_get_playback_volume(elem, 0, &value) >= 0) {
+    long min = 0;
+    long max = 0;
+    if (snd_mixer_selem_get_playback_volume_range(elem, &min, &max) >= 0) {
+      *vol = (float)(value-min)/(float)(max-min);
+    } 
+  }
+  snd_mixer_close(mixer);
+
+  return SA_SUCCESS;
+}
+
+
+
+/*
+ * -----------------------------------------------------------------------------
+ * Unsupported functions
+ * -----------------------------------------------------------------------------
+ */
+#define UNSUPPORTED(func)   func { return SA_ERROR_NOT_SUPPORTED; }
+
+UNSUPPORTED(int sa_stream_create_opaque(sa_stream_t **s, const char *client_name, sa_mode_t mode, const char *codec))
+UNSUPPORTED(int sa_stream_set_write_lower_watermark(sa_stream_t *s, size_t size))
+UNSUPPORTED(int sa_stream_set_read_lower_watermark(sa_stream_t *s, size_t size))
+UNSUPPORTED(int sa_stream_set_write_upper_watermark(sa_stream_t *s, size_t size))
+UNSUPPORTED(int sa_stream_set_read_upper_watermark(sa_stream_t *s, size_t size))
+UNSUPPORTED(int sa_stream_set_channel_map(sa_stream_t *s, const sa_channel_t map[], unsigned int n))
+UNSUPPORTED(int sa_stream_set_xrun_mode(sa_stream_t *s, sa_xrun_mode_t mode))
+UNSUPPORTED(int sa_stream_set_non_interleaved(sa_stream_t *s, int enable))
+UNSUPPORTED(int sa_stream_set_dynamic_rate(sa_stream_t *s, int enable))
+UNSUPPORTED(int sa_stream_set_driver(sa_stream_t *s, const char *driver))
+UNSUPPORTED(int sa_stream_start_thread(sa_stream_t *s, sa_event_callback_t callback))
+UNSUPPORTED(int sa_stream_stop_thread(sa_stream_t *s))
+UNSUPPORTED(int sa_stream_change_device(sa_stream_t *s, const char *device_name))
+UNSUPPORTED(int sa_stream_change_read_volume(sa_stream_t *s, const int32_t vol[], unsigned int n))
+UNSUPPORTED(int sa_stream_change_write_volume(sa_stream_t *s, const int32_t vol[], unsigned int n))
+UNSUPPORTED(int sa_stream_change_rate(sa_stream_t *s, unsigned int rate))
+UNSUPPORTED(int sa_stream_change_meta_data(sa_stream_t *s, const char *name, const void *data, size_t size))
+UNSUPPORTED(int sa_stream_change_user_data(sa_stream_t *s, const void *value))
+UNSUPPORTED(int sa_stream_set_adjust_rate(sa_stream_t *s, sa_adjust_t direction))
+UNSUPPORTED(int sa_stream_set_adjust_nchannels(sa_stream_t *s, sa_adjust_t direction))
+UNSUPPORTED(int sa_stream_set_adjust_pcm_format(sa_stream_t *s, sa_adjust_t direction))
+UNSUPPORTED(int sa_stream_set_adjust_watermarks(sa_stream_t *s, sa_adjust_t direction))
+UNSUPPORTED(int sa_stream_get_mode(sa_stream_t *s, sa_mode_t *access_mode))
+UNSUPPORTED(int sa_stream_get_codec(sa_stream_t *s, char *codec, size_t *size))
+UNSUPPORTED(int sa_stream_get_pcm_format(sa_stream_t *s, sa_pcm_format_t *format))
+UNSUPPORTED(int sa_stream_get_rate(sa_stream_t *s, unsigned int *rate))
+UNSUPPORTED(int sa_stream_get_nchannels(sa_stream_t *s, int *nchannels))
+UNSUPPORTED(int sa_stream_get_user_data(sa_stream_t *s, void **value))
+UNSUPPORTED(int sa_stream_get_write_lower_watermark(sa_stream_t *s, size_t *size))
+UNSUPPORTED(int sa_stream_get_read_lower_watermark(sa_stream_t *s, size_t *size))
+UNSUPPORTED(int sa_stream_get_write_upper_watermark(sa_stream_t *s, size_t *size))
+UNSUPPORTED(int sa_stream_get_read_upper_watermark(sa_stream_t *s, size_t *size))
+UNSUPPORTED(int sa_stream_get_channel_map(sa_stream_t *s, sa_channel_t map[], unsigned int *n))
+UNSUPPORTED(int sa_stream_get_xrun_mode(sa_stream_t *s, sa_xrun_mode_t *mode))
+UNSUPPORTED(int sa_stream_get_non_interleaved(sa_stream_t *s, int *enabled))
+UNSUPPORTED(int sa_stream_get_dynamic_rate(sa_stream_t *s, int *enabled))
+UNSUPPORTED(int sa_stream_get_driver(sa_stream_t *s, char *driver_name, size_t *size))
+UNSUPPORTED(int sa_stream_get_device(sa_stream_t *s, char *device_name, size_t *size))
+UNSUPPORTED(int sa_stream_get_read_volume(sa_stream_t *s, int32_t vol[], unsigned int *n))
+UNSUPPORTED(int sa_stream_get_write_volume(sa_stream_t *s, int32_t vol[], unsigned int *n))
+UNSUPPORTED(int sa_stream_get_meta_data(sa_stream_t *s, const char *name, void*data, size_t *size))
+UNSUPPORTED(int sa_stream_get_adjust_rate(sa_stream_t *s, sa_adjust_t *direction))
+UNSUPPORTED(int sa_stream_get_adjust_nchannels(sa_stream_t *s, sa_adjust_t *direction))
+UNSUPPORTED(int sa_stream_get_adjust_pcm_format(sa_stream_t *s, sa_adjust_t *direction))
+UNSUPPORTED(int sa_stream_get_adjust_watermarks(sa_stream_t *s, sa_adjust_t *direction))
+UNSUPPORTED(int sa_stream_get_state(sa_stream_t *s, sa_state_t *state))
+UNSUPPORTED(int sa_stream_get_event_error(sa_stream_t *s, sa_error_t *error))
+UNSUPPORTED(int sa_stream_get_event_notify(sa_stream_t *s, sa_notify_t *notify))
+UNSUPPORTED(int sa_stream_read(sa_stream_t *s, void *data, size_t nbytes))
+UNSUPPORTED(int sa_stream_read_ni(sa_stream_t *s, unsigned int channel, void *data, size_t nbytes))
+UNSUPPORTED(int sa_stream_write_ni(sa_stream_t *s, unsigned int channel, const void *data, size_t nbytes))
+UNSUPPORTED(int sa_stream_pwrite(sa_stream_t *s, const void *data, size_t nbytes, int64_t offset, sa_seek_t whence))
+UNSUPPORTED(int sa_stream_pwrite_ni(sa_stream_t *s, unsigned int channel, const void *data, size_t nbytes, int64_t offset, sa_seek_t whence))
+UNSUPPORTED(int sa_stream_get_read_size(sa_stream_t *s, size_t *size))
+
+const char *sa_strerror(int code) { return NULL; }
+
new file mode 100644
--- /dev/null
+++ b/media/libsydneyaudio/src/sydney_audio_mac.c
@@ -0,0 +1,720 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Initial Developer of the Original Code is
+ * CSIRO
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s): Michael Martin
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** *
+ */
+
+#include <pthread.h>
+#include <AudioUnit/AudioUnit.h>
+#include "sydney_audio.h"
+
+/*
+ * The Mac's audio interface is based on a "pull" I/O model, which means you
+ * can't just provide a data buffer and tell the audio device to play; you must
+ * register a callback and provide data as the device asks for it. To support
+ * sydney audio's "write-to-play" style interface, we have to buffer up the
+ * data as it arrives and feed it to the callback as required.
+ *
+ * This is handled by a simple linked list of buffers; data is always written
+ * to the tail and read from the head. Each buffer tracks the start and end
+ * positions of its contained data. Buffers are allocated when the tail buffer
+ * fills, and freed when the head buffer empties. There is always at least one
+ * buffer allocated.
+ *
+ *       s   e      s      e      s  e            + data read
+ *    +++#####  ->  ########  ->  ####----        # data written
+ *    ^                           ^               - empty
+ *    bl_head                     bl_tail
+ */
+
+typedef struct sa_buf sa_buf;
+struct sa_buf {
+  unsigned int      size;
+  unsigned int      start;
+  unsigned int      end;
+  sa_buf          * next;
+  unsigned char     data[0];
+};
+
+struct sa_stream {
+  AudioUnit         output_unit;
+  pthread_mutex_t   mutex;
+  bool              playing;
+  int64_t           bytes_played;
+
+  /* audio format info */
+  unsigned int      rate;
+  unsigned int      n_channels;
+  unsigned int      bytes_per_ch;
+
+  /* buffer list */
+  sa_buf          * bl_head;
+  sa_buf          * bl_tail;
+  int               n_bufs;
+};
+
+
+/*
+ * Use a default buffer size with enough room for one second of audio,
+ * assuming stereo data at 44.1kHz with 32 bits per channel, and impose
+ * a generous limit on the number of buffers.
+ */
+#define BUF_SIZE    (2 * 44100 * 4)
+#define BUF_LIMIT   5
+
+#if BUF_LIMIT < 2
+#error BUF_LIMIT must be at least 2!
+#endif
+
+
+static OSStatus audio_callback(void *arg, AudioUnitRenderActionFlags *action_flags,
+  const AudioTimeStamp *time_stamp, UInt32 bus_num, UInt32 n_frames, AudioBufferList *data);
+
+static sa_buf *new_buffer(void);
+
+
+/*
+ * -----------------------------------------------------------------------------
+ * Startup and shutdown functions
+ * -----------------------------------------------------------------------------
+ */
+
+int
+sa_stream_create_pcm(
+  sa_stream_t      ** _s,
+  const char        * client_name,
+  sa_mode_t           mode,
+  sa_pcm_format_t     format,
+  unsigned  int       rate,
+  unsigned  int       n_channels
+) {
+
+  /*
+   * Make sure we return a NULL stream pointer on failure.
+   */
+  if (_s == NULL) {
+    return SA_ERROR_INVALID;
+  }
+  *_s = NULL;
+
+  if (mode != SA_MODE_WRONLY) {
+    return SA_ERROR_NOT_SUPPORTED;
+  }
+  if (format != SA_PCM_FORMAT_S16_LE) {
+    return SA_ERROR_NOT_SUPPORTED;
+  }
+
+  /*
+   * Allocate the instance and required resources.
+   */
+  sa_stream_t   * s;
+  if ((s = malloc(sizeof(sa_stream_t))) == NULL) {
+    return SA_ERROR_OOM;
+  }
+  if ((s->bl_head = new_buffer()) == NULL) {
+    free(s);
+    return SA_ERROR_OOM;
+  }
+  if (pthread_mutex_init(&s->mutex, NULL) != 0) {
+    free(s->bl_head);
+    free(s);
+    return SA_ERROR_SYSTEM;
+  }
+
+  s->output_unit  = NULL;
+  s->playing      = FALSE;
+  s->bytes_played = 0;
+  s->rate         = rate;
+  s->n_channels   = n_channels;
+  s->bytes_per_ch = 2;
+  s->bl_tail      = s->bl_head;
+  s->n_bufs       = 1;
+
+  *_s = s;
+  return SA_SUCCESS;
+}
+
+
+int
+sa_stream_open(sa_stream_t *s) {
+
+  if (s == NULL) {
+    return SA_ERROR_NO_INIT;
+  }
+  if (s->output_unit != NULL) {
+    return SA_ERROR_INVALID;
+  }
+
+  /*
+   * Open the default audio output unit.
+   */
+  ComponentDescription desc;
+  desc.componentType         = kAudioUnitType_Output;
+  desc.componentSubType      = kAudioUnitSubType_DefaultOutput;
+  desc.componentManufacturer = kAudioUnitManufacturer_Apple;
+  desc.componentFlags        = 0;
+  desc.componentFlagsMask    = 0;
+
+  Component comp = FindNextComponent(NULL, &desc);
+  if (comp == NULL) {
+    return SA_ERROR_NO_DEVICE;
+  }
+
+  if (OpenAComponent(comp, &s->output_unit) != noErr) {
+    return SA_ERROR_NO_DEVICE;
+  }
+
+  /*
+   * Set up the render callback used to feed audio data into the output unit.
+   */
+  AURenderCallbackStruct input;
+  input.inputProc       = audio_callback;
+  input.inputProcRefCon = s;
+  if (AudioUnitSetProperty(s->output_unit, kAudioUnitProperty_SetRenderCallback,
+      kAudioUnitScope_Input, 0, &input, sizeof(input)) != 0) {
+    return SA_ERROR_SYSTEM;
+  }
+
+  /*
+   * Set up the format description for our audio data. Apple uses the
+   * following terminology:
+   *
+   * sample = a single data value for one channel
+   * frame  = a set of samples that includes one sample for each channel
+   * packet = the smallest indivisible block of audio data; for uncompressed
+   *          audio (which is what we have), this is one frame
+   * rate   = the number of complete frames per second
+   *
+   * Note that this definition of frame differs from, well, pretty much everyone
+   * else's. See this really long link for more info:
+   *
+   * http://developer.apple.com/documentation/MusicAudio/Reference/CoreAudioDataTypesRef/Reference/reference.html#//apple_ref/c/tdef/AudioStreamBasicDescription
+   */
+  AudioStreamBasicDescription fmt;
+  fmt.mFormatID         = kAudioFormatLinearPCM;
+  fmt.mFormatFlags      = kLinearPCMFormatFlagIsSignedInteger |
+#ifdef __BIG_ENDIAN__
+                          kLinearPCMFormatFlagIsBigEndian |
+#endif
+                          kLinearPCMFormatFlagIsPacked;
+  fmt.mSampleRate       = s->rate;
+  fmt.mChannelsPerFrame = s->n_channels;
+  fmt.mBitsPerChannel   = s->bytes_per_ch * 8;
+  fmt.mFramesPerPacket  = 1;  /* uncompressed audio */
+  fmt.mBytesPerFrame    = fmt.mChannelsPerFrame * fmt.mBitsPerChannel / 8;
+  fmt.mBytesPerPacket   = fmt.mBytesPerFrame * fmt.mFramesPerPacket;
+
+  /*
+   * We're feeding data in to the output bus of the audio system, so we set
+   * the format description on the input scope of the device, using the very
+   * obvious element value of 0 to indicate the output bus.
+   *
+   * http://developer.apple.com/technotes/tn2002/tn2091.html
+   */
+  if (AudioUnitSetProperty(s->output_unit, kAudioUnitProperty_StreamFormat,
+      kAudioUnitScope_Input, 0, &fmt, sizeof(AudioStreamBasicDescription)) != 0) {
+    return SA_ERROR_NOT_SUPPORTED;
+  }
+
+  if (AudioUnitInitialize(s->output_unit) != 0) {
+    return SA_ERROR_SYSTEM;
+  }
+
+  return SA_SUCCESS;
+}
+
+
+int
+sa_stream_destroy(sa_stream_t *s) {
+
+  if (s == NULL) {
+    return SA_SUCCESS;
+  }
+
+  pthread_mutex_lock(&s->mutex);
+
+  /*
+   * Shut down the audio output device.
+   */
+  int result = SA_SUCCESS;
+  if (s->output_unit != NULL) {
+    if (s->playing && AudioOutputUnitStop(s->output_unit) != 0) {
+      result = SA_ERROR_SYSTEM;
+    }
+    if (AudioUnitUninitialize(s->output_unit) != 0) {
+      result = SA_ERROR_SYSTEM;
+    }
+    if (CloseComponent(s->output_unit) != noErr) {
+      result = SA_ERROR_SYSTEM;
+    }
+  }
+
+  pthread_mutex_unlock(&s->mutex);
+
+  /*
+   * Release resources.
+   */
+  if (pthread_mutex_destroy(&s->mutex) != 0) {
+    result = SA_ERROR_SYSTEM;
+  }
+  while (s->bl_head != NULL) {
+    sa_buf  * next = s->bl_head->next;
+    free(s->bl_head);
+    s->bl_head = next;
+  }
+  free(s);
+
+  return result;
+}
+
+
+
+/*
+ * -----------------------------------------------------------------------------
+ * Data read and write functions
+ * -----------------------------------------------------------------------------
+ */
+
+int
+sa_stream_write(sa_stream_t *s, const void *data, size_t nbytes) {
+
+  if (s == NULL || s->output_unit == NULL) {
+    return SA_ERROR_NO_INIT;
+  }
+  if (nbytes == 0) {
+    return SA_SUCCESS;
+  }
+
+  pthread_mutex_lock(&s->mutex);
+
+  /*
+   * Append the new data to the end of our buffer list.
+   */
+  int result = SA_SUCCESS;
+  while (1) {
+    unsigned int avail = s->bl_tail->size - s->bl_tail->end;
+
+    if (nbytes <= avail) {
+
+      /*
+       * The new data will fit into the current tail buffer, so
+       * just copy it in and we're done.
+       */
+      memcpy(s->bl_tail->data + s->bl_tail->end, data, nbytes);
+      s->bl_tail->end += nbytes;
+      break;
+
+    } else {
+
+      /*
+       * Copy what we can into the tail and allocate a new buffer
+       * for the rest.
+       */
+      memcpy(s->bl_tail->data + s->bl_tail->end, data, avail);
+      s->bl_tail->end += avail;
+      data = ((unsigned char *)data) + avail;
+      nbytes -= avail;
+
+      /* 
+       * If we still have data left to copy but we've hit the limit of
+       * allowable buffer allocations, we need to spin for a bit to allow
+       * the audio callback function to slurp some more data up.
+       */
+      if (nbytes > 0 && s->n_bufs == BUF_LIMIT) {
+#ifdef TIMING_TRACE
+        printf("#");  /* too much audio data */
+#endif
+        if (!s->playing) {
+          /*
+           * We haven't even started playing yet! That means the
+           * BUF_SIZE/BUF_LIMIT values are too low... Not much we can
+           * do here; spinning won't help because the audio callback
+           * hasn't been enabled yet. Oh well, error time.
+           */
+          printf("Too much audio data received before audio device enabled!\n");
+          result = SA_ERROR_SYSTEM;
+          break;
+        }
+        while (s->n_bufs == BUF_LIMIT) {
+          pthread_mutex_unlock(&s->mutex);
+          struct timespec ts = {0, 1000000};
+          nanosleep(&ts, NULL);
+          pthread_mutex_lock(&s->mutex);
+        }
+      }
+
+      /* 
+       * Allocate a new tail buffer, and go 'round again to fill it up.
+       */
+      if ((s->bl_tail->next = new_buffer()) == NULL) {
+        result = SA_ERROR_OOM;
+        break;
+      }
+      s->n_bufs++;
+      s->bl_tail = s->bl_tail->next;
+    
+    } /* if (nbytes <= avail), else */
+
+  } /* while (1) */
+
+  pthread_mutex_unlock(&s->mutex);
+
+  /*
+   * Once we have our first block of audio data, enable the audio callback
+   * function. This doesn't need to be protected by the mutex, because
+   * s->playing is not used in the audio callback thread, and it's probably
+   * better not to be inside the lock when we enable the audio callback.
+   */
+  if (!s->playing) {
+    s->playing = TRUE;
+    if (AudioOutputUnitStart(s->output_unit) != 0) {
+      result = SA_ERROR_SYSTEM;
+    }
+  }
+
+  return result;
+}
+
+
+static OSStatus
+audio_callback(
+  void                        * arg,
+  AudioUnitRenderActionFlags  * action_flags,
+  const AudioTimeStamp        * time_stamp,
+  UInt32                        bus_num,
+  UInt32                        n_frames,
+  AudioBufferList             * data
+) {
+
+#ifdef TIMING_TRACE
+  printf(".");  /* audio read 'tick' */
+#endif
+
+  /*
+   * We're dealing with interleaved data, so the system should only
+   * have provided one buffer to be filled.
+   */
+  assert(data->mNumberBuffers == 1);
+
+  sa_stream_t     * s = arg;
+
+  pthread_mutex_lock(&s->mutex);
+
+  unsigned char   * dst             = data->mBuffers[0].mData;
+  unsigned int      bytes_per_frame = s->n_channels * s->bytes_per_ch;
+  unsigned int      bytes_to_copy   = n_frames * bytes_per_frame;
+
+  /*
+   * Keep track of the number of bytes we've consumed so far. mSampleTime
+   * is actually the number of *frames* that have been consumed by the
+   * audio output unit so far. I don't know why it's a float.
+   */
+  assert(time_stamp->mFlags & kAudioTimeStampSampleTimeValid);
+  s->bytes_played = (int64_t)time_stamp->mSampleTime * bytes_per_frame;
+
+  /*
+   * Consume data from the start of the buffer list.
+   */
+  while (1) {
+    assert(s->bl_head->start <= s->bl_head->end);
+    unsigned int avail = s->bl_head->end - s->bl_head->start;
+
+    if (avail >= bytes_to_copy) {
+
+      /*
+       * We have all we need in the head buffer, so just grab it and go.
+       */
+      memcpy(dst, s->bl_head->data + s->bl_head->start, bytes_to_copy);
+      s->bl_head->start += bytes_to_copy;
+      break;
+
+    } else {
+
+      /*
+       * Copy what we can from the head and move on to the next buffer.
+       */
+      memcpy(dst, s->bl_head->data + s->bl_head->start, avail);
+      s->bl_head->start += avail;
+      dst += avail;
+      bytes_to_copy -= avail;
+
+      /*
+       * We want to free the now-empty buffer, but not if it's also the
+       * current tail. If it is the tail, we don't have enough data to fill
+       * the destination buffer, so we'll just zero it out and give up.
+       */
+      sa_buf  * next = s->bl_head->next;
+      if (next == NULL) {
+#ifdef TIMING_TRACE
+        printf("!");  /* not enough audio data */
+#endif
+        memset(dst, 0, bytes_to_copy);
+        break;
+      }
+      free(s->bl_head);
+      s->bl_head = next;
+      s->n_bufs--;
+
+    } /* if (avail >= bytes_to_copy), else */
+
+  } /* while (1) */
+
+  pthread_mutex_unlock(&s->mutex);
+  return noErr;
+}
+
+
+
+/*
+ * -----------------------------------------------------------------------------
+ * General query and support functions
+ * -----------------------------------------------------------------------------
+ */
+
+int
+sa_stream_get_write_size(sa_stream_t *s, size_t *size) {
+
+  if (s == NULL || s->output_unit == NULL) {
+    return SA_ERROR_NO_INIT;
+  }
+
+  pthread_mutex_lock(&s->mutex);
+
+  /*
+   * The sum of the free space in the tail buffer plus the size of any new
+   * buffers represents the write space available before blocking.
+   */
+  unsigned int avail = s->bl_tail->size - s->bl_tail->end;
+  avail += (BUF_LIMIT - s->n_bufs) * BUF_SIZE;
+  *size = avail;
+
+  pthread_mutex_unlock(&s->mutex);
+  return SA_SUCCESS;
+}
+
+
+int
+sa_stream_get_position(sa_stream_t *s, sa_position_t position, int64_t *pos) {
+
+  if (s == NULL || s->output_unit == NULL) {
+    return SA_ERROR_NO_INIT;
+  }
+  if (position != SA_POSITION_WRITE_SOFTWARE) {
+    return SA_ERROR_NOT_SUPPORTED;
+  }
+
+  pthread_mutex_lock(&s->mutex);
+  *pos = s->bytes_played;
+  pthread_mutex_unlock(&s->mutex);
+  return SA_SUCCESS;
+}
+
+
+int
+sa_stream_pause(sa_stream_t *s) {
+
+  if (s == NULL || s->output_unit == NULL) {
+    return SA_ERROR_NO_INIT;
+  }
+
+  pthread_mutex_lock(&s->mutex);
+  AudioOutputUnitStop(s->output_unit);
+  pthread_mutex_unlock(&s->mutex);
+  return SA_SUCCESS;
+}
+
+
+int
+sa_stream_resume(sa_stream_t *s) {
+
+  if (s == NULL || s->output_unit == NULL) {
+    return SA_ERROR_NO_INIT;
+  }
+
+  pthread_mutex_lock(&s->mutex);
+
+  /*
+   * The audio device resets its mSampleTime counter after pausing,
+   * so we need to clear our tracking value to keep that in sync.
+   */
+  s->bytes_played = 0;
+  AudioOutputUnitStart(s->output_unit);
+
+  pthread_mutex_unlock(&s->mutex);
+  return SA_SUCCESS;
+}
+
+
+static sa_buf *
+new_buffer(void) {
+  sa_buf  * b = malloc(sizeof(sa_buf) + BUF_SIZE);
+  if (b != NULL) {
+    b->size  = BUF_SIZE;
+    b->start = 0;
+    b->end   = 0;
+    b->next  = NULL;
+  }
+  return b;
+}
+
+
+int
+sa_stream_drain(sa_stream_t *s)
+{
+  if (s == NULL || s->output_unit == NULL) {
+    return SA_ERROR_NO_INIT;
+  }
+
+  while (1) {
+    pthread_mutex_lock(&s->mutex);
+    sa_buf  * b;
+    size_t    used = 0;
+    for (b = s->bl_head; b != NULL; b = b->next) {
+      used += b->end - b->start;
+    }
+    pthread_mutex_unlock(&s->mutex);
+
+    if (used == 0) {
+      break;
+    }
+
+    struct timespec ts = {0, 1000000};
+    nanosleep(&ts, NULL);
+  }
+  return SA_SUCCESS;
+}
+
+
+
+/*
+ * -----------------------------------------------------------------------------
+ * Extension functions
+ * -----------------------------------------------------------------------------
+ */
+
+int
+sa_stream_set_volume_abs(sa_stream_t *s, float vol) {
+
+  if (s == NULL || s->output_unit == NULL) {
+    return SA_ERROR_NO_INIT;
+  }
+
+  pthread_mutex_lock(&s->mutex);
+  AudioUnitSetParameter(s->output_unit, kHALOutputParam_Volume,
+      kAudioUnitParameterFlag_Output, 0, vol, 0);
+  pthread_mutex_unlock(&s->mutex);
+  return SA_SUCCESS;
+}
+
+
+int
+sa_stream_get_volume_abs(sa_stream_t *s, float *vol) {
+
+  if (s == NULL || s->output_unit == NULL) {
+    return SA_ERROR_NO_INIT;
+  }
+
+  pthread_mutex_lock(&s->mutex);
+  Float32 local_vol = 0;
+  AudioUnitGetParameter(s->output_unit, kHALOutputParam_Volume,
+      kAudioUnitParameterFlag_Output, 0, &local_vol);
+  *vol = local_vol;
+  pthread_mutex_unlock(&s->mutex);
+  return SA_SUCCESS;
+}
+
+
+
+/*
+ * -----------------------------------------------------------------------------
+ * Unsupported functions
+ * -----------------------------------------------------------------------------
+ */
+#define UNSUPPORTED(func)   func { return SA_ERROR_NOT_SUPPORTED; }
+
+UNSUPPORTED(int sa_stream_create_opaque(sa_stream_t **s, const char *client_name, sa_mode_t mode, const char *codec))
+UNSUPPORTED(int sa_stream_set_write_lower_watermark(sa_stream_t *s, size_t size))
+UNSUPPORTED(int sa_stream_set_read_lower_watermark(sa_stream_t *s, size_t size))
+UNSUPPORTED(int sa_stream_set_write_upper_watermark(sa_stream_t *s, size_t size))
+UNSUPPORTED(int sa_stream_set_read_upper_watermark(sa_stream_t *s, size_t size))
+UNSUPPORTED(int sa_stream_set_channel_map(sa_stream_t *s, const sa_channel_t map[], unsigned int n))
+UNSUPPORTED(int sa_stream_set_xrun_mode(sa_stream_t *s, sa_xrun_mode_t mode))
+UNSUPPORTED(int sa_stream_set_non_interleaved(sa_stream_t *s, int enable))
+UNSUPPORTED(int sa_stream_set_dynamic_rate(sa_stream_t *s, int enable))
+UNSUPPORTED(int sa_stream_set_driver(sa_stream_t *s, const char *driver))
+UNSUPPORTED(int sa_stream_start_thread(sa_stream_t *s, sa_event_callback_t callback))
+UNSUPPORTED(int sa_stream_stop_thread(sa_stream_t *s))
+UNSUPPORTED(int sa_stream_change_device(sa_stream_t *s, const char *device_name))
+UNSUPPORTED(int sa_stream_change_read_volume(sa_stream_t *s, const int32_t vol[], unsigned int n))
+UNSUPPORTED(int sa_stream_change_write_volume(sa_stream_t *s, const int32_t vol[], unsigned int n))
+UNSUPPORTED(int sa_stream_change_rate(sa_stream_t *s, unsigned int rate))
+UNSUPPORTED(int sa_stream_change_meta_data(sa_stream_t *s, const char *name, const void *data, size_t size))
+UNSUPPORTED(int sa_stream_change_user_data(sa_stream_t *s, const void *value))
+UNSUPPORTED(int sa_stream_set_adjust_rate(sa_stream_t *s, sa_adjust_t direction))
+UNSUPPORTED(int sa_stream_set_adjust_nchannels(sa_stream_t *s, sa_adjust_t direction))
+UNSUPPORTED(int sa_stream_set_adjust_pcm_format(sa_stream_t *s, sa_adjust_t direction))
+UNSUPPORTED(int sa_stream_set_adjust_watermarks(sa_stream_t *s, sa_adjust_t direction))
+UNSUPPORTED(int sa_stream_get_mode(sa_stream_t *s, sa_mode_t *access_mode))
+UNSUPPORTED(int sa_stream_get_codec(sa_stream_t *s, char *codec, size_t *size))
+UNSUPPORTED(int sa_stream_get_pcm_format(sa_stream_t *s, sa_pcm_format_t *format))
+UNSUPPORTED(int sa_stream_get_rate(sa_stream_t *s, unsigned int *rate))
+UNSUPPORTED(int sa_stream_get_nchannels(sa_stream_t *s, int *nchannels))
+UNSUPPORTED(int sa_stream_get_user_data(sa_stream_t *s, void **value))
+UNSUPPORTED(int sa_stream_get_write_lower_watermark(sa_stream_t *s, size_t *size))
+UNSUPPORTED(int sa_stream_get_read_lower_watermark(sa_stream_t *s, size_t *size))
+UNSUPPORTED(int sa_stream_get_write_upper_watermark(sa_stream_t *s, size_t *size))
+UNSUPPORTED(int sa_stream_get_read_upper_watermark(sa_stream_t *s, size_t *size))
+UNSUPPORTED(int sa_stream_get_channel_map(sa_stream_t *s, sa_channel_t map[], unsigned int *n))
+UNSUPPORTED(int sa_stream_get_xrun_mode(sa_stream_t *s, sa_xrun_mode_t *mode))
+UNSUPPORTED(int sa_stream_get_non_interleaved(sa_stream_t *s, int *enabled))
+UNSUPPORTED(int sa_stream_get_dynamic_rate(sa_stream_t *s, int *enabled))
+UNSUPPORTED(int sa_stream_get_driver(sa_stream_t *s, char *driver_name, size_t *size))
+UNSUPPORTED(int sa_stream_get_device(sa_stream_t *s, char *device_name, size_t *size))
+UNSUPPORTED(int sa_stream_get_read_volume(sa_stream_t *s, int32_t vol[], unsigned int *n))
+UNSUPPORTED(int sa_stream_get_write_volume(sa_stream_t *s, int32_t vol[], unsigned int *n))
+UNSUPPORTED(int sa_stream_get_meta_data(sa_stream_t *s, const char *name, void*data, size_t *size))
+UNSUPPORTED(int sa_stream_get_adjust_rate(sa_stream_t *s, sa_adjust_t *direction))
+UNSUPPORTED(int sa_stream_get_adjust_nchannels(sa_stream_t *s, sa_adjust_t *direction))
+UNSUPPORTED(int sa_stream_get_adjust_pcm_format(sa_stream_t *s, sa_adjust_t *direction))
+UNSUPPORTED(int sa_stream_get_adjust_watermarks(sa_stream_t *s, sa_adjust_t *direction))
+UNSUPPORTED(int sa_stream_get_state(sa_stream_t *s, sa_state_t *state))
+UNSUPPORTED(int sa_stream_get_event_error(sa_stream_t *s, sa_error_t *error))
+UNSUPPORTED(int sa_stream_get_event_notify(sa_stream_t *s, sa_notify_t *notify))
+UNSUPPORTED(int sa_stream_read(sa_stream_t *s, void *data, size_t nbytes))
+UNSUPPORTED(int sa_stream_read_ni(sa_stream_t *s, unsigned int channel, void *data, size_t nbytes))
+UNSUPPORTED(int sa_stream_write_ni(sa_stream_t *s, unsigned int channel, const void *data, size_t nbytes))
+UNSUPPORTED(int sa_stream_pwrite(sa_stream_t *s, const void *data, size_t nbytes, int64_t offset, sa_seek_t whence))
+UNSUPPORTED(int sa_stream_pwrite_ni(sa_stream_t *s, unsigned int channel, const void *data, size_t nbytes, int64_t offset, sa_seek_t whence))
+UNSUPPORTED(int sa_stream_get_read_size(sa_stream_t *s, size_t *size))
+
+const char *sa_strerror(int code) { return NULL; }
+
new file mode 100644
--- /dev/null
+++ b/media/libsydneyaudio/src/sydney_audio_oss.c
@@ -0,0 +1,719 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Initial Developer of the Original Code is
+ * CSIRO
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s): Michael Martin
+ *                 Chris Double (chris.double@double.co.nz)
+ *                 Jeremy D. Lea (reg@openpave.org)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/soundcard.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <pthread.h>
+#include <assert.h>
+#include "sydney_audio.h"
+
+// for versions newer than 3.6.1
+#define OSS_VERSION(x, y, z) (x << 16 | y << 8 | z)
+// support only versions newer than 3.6.1
+#define SUPP_OSS_VERSION OSS_VERSION(3,6,1)
+
+#if (SOUND_VERSION < SUPP_OSS_VERSION)
+#error Unsupported OSS Version
+#else
+
+typedef struct sa_buf sa_buf;
+struct sa_buf {
+  unsigned int      size;
+  unsigned int      start;
+  unsigned int      end;
+  sa_buf          * next;
+  unsigned char     data[0];
+};
+
+struct sa_stream {
+  char*                output_unit;
+  int                output_fd;
+  pthread_t         thread_id;
+  pthread_mutex_t   mutex;
+  char              playing;
+  int64_t           bytes_played;
+
+  /* audio format info */
+  unsigned int      rate;
+  unsigned int      channels;
+  int               format;
+
+  /* buffer list */
+  sa_buf          * bl_head;
+  sa_buf          * bl_tail;
+  int               n_bufs;
+};
+
+
+/*
+ * Use a default buffer size with enough room for one second of audio,
+ * assuming stereo data at 44.1kHz with 32 bits per channel, and impose
+ * a generous limit on the number of buffers.
+ */
+#define BUF_SIZE    (2 * 44100 * 4)
+#define BUF_LIMIT   5
+
+#if BUF_LIMIT < 2
+#error BUF_LIMIT must be at least 2!
+#endif
+
+static void audio_callback(void* s);
+static sa_buf *new_buffer(void);
+
+/** Private functions - implementation specific */
+
+/*!
+ * \brief private function mapping Sudney Audio format to OSS formats
+ * \param format - Sydney Audio API specific format
+ * \param - filled by the function with a value for corresponding OSS format
+ * \return - Sydney API error value as in ::sa_pcm_format_t
+ * */
+static int oss_audio_format(sa_pcm_format_t sa_format, int *fmt) {
+    *fmt = -1;
+    switch (sa_format) {
+        case SA_PCM_FORMAT_U8:
+            *fmt = AFMT_U8;
+            break;
+        case SA_PCM_FORMAT_ULAW:
+            *fmt = AFMT_MU_LAW;
+            break;
+        case SA_PCM_FORMAT_ALAW:
+            *fmt = AFMT_A_LAW;
+            break;
+        /* 16-bit little endian (LE) format */
+        case SA_PCM_FORMAT_S16_LE:
+            *fmt = AFMT_S16_LE;
+            break;
+        /* 16-bit big endian (BE) format */
+        case SA_PCM_FORMAT_S16_BE:
+            *fmt = AFMT_S16_BE;
+            break;
+#if SOUND_VERSION >= OSS_VERSION(4,0,0)
+        /* 24-bit formats (LSB aligned in 32 bit word) */
+        case SA_PCM_FORMAT_S24_LE:
+            *fmt = AFMT_S24_LE;
+            break;
+        /* 24-bit formats (LSB aligned in 32 bit word) */
+        case SA_PCM_FORMAT_S24_BE:
+            *fmt = AFMT_S24_BE;
+            break;
+        /* 32-bit format little endian */
+        case SA_PCM_FORMAT_S32_LE:
+            *fmt = AFMT_S32_LE;
+            break;
+        /* 32-bit format big endian */
+        case SA_PCM_FORMAT_S32_BE:
+            *fmt = AFMT_S32_BE;
+            break;
+#endif
+        default:
+            return SA_ERROR_NOT_SUPPORTED;
+            break;
+    }
+    return SA_SUCCESS;
+}
+
+/*
+ * -----------------------------------------------------------------------------
+ * Startup and shutdown functions
+ * -----------------------------------------------------------------------------
+ */
+
+int
+sa_stream_create_pcm(
+  sa_stream_t      ** _s,
+  const char        * client_name,
+  sa_mode_t           mode,
+  sa_pcm_format_t     format,
+  unsigned  int       rate,
+  unsigned  int       channels
+) {
+  sa_stream_t * s = 0;
+  int fmt = 0;
+
+  /*
+   * Make sure we return a NULL stream pointer on failure.
+   */
+  if (_s == NULL) {
+    return SA_ERROR_INVALID;
+  }
+  *_s = NULL;
+
+  if (mode != SA_MODE_WRONLY) {
+    return SA_ERROR_NOT_SUPPORTED;
+  }
+  if (oss_audio_format(format, &fmt) != SA_SUCCESS) {
+    return SA_ERROR_NOT_SUPPORTED;
+  }
+
+  /*
+   * Allocate the instance and required resources.
+   */
+  if ((s = malloc(sizeof(sa_stream_t))) == NULL) {
+    return SA_ERROR_OOM;
+  }
+  if ((s->bl_head = new_buffer()) == NULL) {
+    free(s);
+    return SA_ERROR_OOM;
+  }
+  if (pthread_mutex_init(&s->mutex, NULL) != 0) {
+    free(s->bl_head);
+    free(s);
+    return SA_ERROR_SYSTEM;
+  }
+
+  s->output_unit  = "/dev/dsp";
+  s->output_fd    = -1;
+  s->thread_id    = 0;
+  s->playing      = 0;
+  s->bytes_played = 0;
+  s->rate         = rate;
+  s->channels     = channels;
+  s->format       = fmt;
+  s->bl_tail      = s->bl_head;
+  s->n_bufs       = 1;
+
+  *_s = s;
+  return SA_SUCCESS;
+}
+
+
+int
+sa_stream_open(sa_stream_t *s) {
+  if (s == NULL) {
+    return SA_ERROR_NO_INIT;
+  }
+  if (s->output_unit == NULL || s->output_fd != -1) {
+    return SA_ERROR_INVALID;
+  }
+
+  // open the default OSS device
+  if ((s->output_fd = open(s->output_unit, O_WRONLY, 0)) == -1) {
+    return SA_ERROR_NO_DEVICE;
+  }
+
+  // set the playback rate
+  if (ioctl(s->output_fd, SNDCTL_DSP_SPEED, &(s->rate)) < 0) {
+    close(s->output_fd);
+    s->output_fd = -1;
+    return SA_ERROR_NOT_SUPPORTED;
+  }
+
+  // set the channel numbers
+  if (ioctl(s->output_fd, SNDCTL_DSP_CHANNELS, &(s->channels)) < 0) {
+    close(s->output_fd);
+    s->output_fd = -1;
+    return SA_ERROR_NOT_SUPPORTED;
+  }
+
+  if (ioctl(s->output_fd, SNDCTL_DSP_SETFMT, &(s->format)) < 0 ) {
+    close(s->output_fd);
+    s->output_fd = -1;
+    return SA_ERROR_NOT_SUPPORTED;
+  }
+
+  return SA_SUCCESS;
+}
+
+
+int
+sa_stream_destroy(sa_stream_t *s) {
+  int result = SA_SUCCESS;
+
+  if (s == NULL) {
+    return SA_SUCCESS;
+  }
+
+  pthread_mutex_lock(&s->mutex);
+
+  /*
+   * This causes the thread sending data to ALSA to stop
+   */
+  s->thread_id = 0;
+
+  /*
+   * Shut down the audio output device.
+   */
+  if (s->output_fd != -1) {
+    if (s->playing && close(s->output_fd) < 0) {
+      result = SA_ERROR_SYSTEM;
+    }
+  }
+
+  pthread_mutex_unlock(&s->mutex);
+
+  /*
+   * Release resources.
+   */
+  if (pthread_mutex_destroy(&s->mutex) != 0) {
+    result = SA_ERROR_SYSTEM;
+  }
+  while (s->bl_head != NULL) {
+    sa_buf  * next = s->bl_head->next;
+    free(s->bl_head);
+    s->bl_head = next;
+  }
+  free(s);
+
+  return result;
+}
+
+
+
+/*
+ * -----------------------------------------------------------------------------
+ * Data read and write functions
+ * -----------------------------------------------------------------------------
+ */
+
+int
+sa_stream_write(sa_stream_t *s, const void *data, size_t nbytes) {
+  int result = SA_SUCCESS;
+
+  if (s == NULL || s->output_unit == NULL) {
+    return SA_ERROR_NO_INIT;
+  }
+  if (nbytes == 0) {
+    return SA_SUCCESS;
+  }
+
+  pthread_mutex_lock(&s->mutex);
+
+  /*
+   * Append the new data to the end of our buffer list.
+   */
+  while (1) {
+    unsigned int avail = s->bl_tail->size - s->bl_tail->end;
+
+    if (nbytes <= avail) {
+
+      /*
+       * The new data will fit into the current tail buffer, so
+       * just copy it in and we're done.
+       */
+      memcpy(s->bl_tail->data + s->bl_tail->end, data, nbytes);
+      s->bl_tail->end += nbytes;
+      break;
+
+    } else {
+
+      /*
+       * Copy what we can into the tail and allocate a new buffer
+       * for the rest.
+       */
+      memcpy(s->bl_tail->data + s->bl_tail->end, data, avail);
+      s->bl_tail->end += avail;
+      data = ((unsigned char *)data) + avail;
+      nbytes -= avail;
+
+      /*
+       * If we still have data left to copy but we've hit the limit of
+       * allowable buffer allocations, we need to spin for a bit to allow
+       * the audio callback function to slurp some more data up.
+       */
+      if (nbytes > 0 && s->n_bufs == BUF_LIMIT) {
+#ifdef TIMING_TRACE
+        printf("#");  /* too much audio data */
+#endif
+        if (!s->playing) {
+          /*
+           * We haven't even started playing yet! That means the
+           * BUF_SIZE/BUF_LIMIT values are too low... Not much we can
+           * do here; spinning won't help because the audio callback
+           * hasn't been enabled yet. Oh well, error time.
+           */
+          printf("Too much audio data received before audio device enabled!\n");
+          result = SA_ERROR_SYSTEM;
+          break;
+        }
+        while (s->n_bufs == BUF_LIMIT) {
+          struct timespec ts = {0, 1000000};
+          pthread_mutex_unlock(&s->mutex);
+          nanosleep(&ts, NULL);
+          pthread_mutex_lock(&s->mutex);
+        }
+      }
+
+      /*
+       * Allocate a new tail buffer, and go 'round again to fill it up.
+       */
+      if ((s->bl_tail->next = new_buffer()) == NULL) {
+        result = SA_ERROR_OOM;
+        break;
+      }
+      s->n_bufs++;
+      s->bl_tail = s->bl_tail->next;
+
+    } /* if (nbytes <= avail), else */
+
+  } /* while (1) */
+
+  pthread_mutex_unlock(&s->mutex);
+
+  /*
+   * Once we have our first block of audio data, enable the audio callback
+   * function. This doesn't need to be protected by the mutex, because
+   * s->playing is not used in the audio callback thread, and it's probably
+   * better not to be inside the lock when we enable the audio callback.
+   */
+  if (!s->playing) {
+    s->playing = 1;
+    if (pthread_create(&s->thread_id, NULL, (void *)audio_callback, s) != 0) {
+      result = SA_ERROR_SYSTEM;
+    }
+  }
+
+  return result;
+}
+
+
+static void audio_callback(void* data)
+{
+  sa_stream_t* s = (sa_stream_t*)data;
+  audio_buf_info info;
+  char* buffer = 0;
+  unsigned int avail;
+  int frames;
+
+#ifdef TIMING_TRACE
+  printf(".");  /* audio read 'tick' */
+#endif
+
+  ioctl(s->output_fd, SNDCTL_DSP_GETOSPACE, &info);
+  buffer = malloc(info.bytes);
+
+  while(1) {
+    char* dst = buffer;
+    unsigned int bytes_to_copy = info.bytes;
+    int bytes = info.bytes;
+
+    pthread_mutex_lock(&s->mutex);
+    if (!s->thread_id)
+      break;
+
+    /*
+     * Consume data from the start of the buffer list.
+     */
+    while (1) {
+      assert(s->bl_head->start <= s->bl_head->end);
+      avail = s->bl_head->end - s->bl_head->start;
+
+      if (avail >= bytes_to_copy) {
+        /*
+         * We have all we need in the head buffer, so just grab it and go.
+         */
+        memcpy(dst, s->bl_head->data + s->bl_head->start, bytes_to_copy);
+        s->bl_head->start += bytes_to_copy;
+        s->bytes_played += bytes_to_copy;
+        break;
+
+      } else {
+
+        sa_buf* next = 0;
+        /*
+         * Copy what we can from the head and move on to the next buffer.
+         */
+        memcpy(dst, s->bl_head->data + s->bl_head->start, avail);
+        s->bl_head->start += avail;
+        dst += avail;
+        bytes_to_copy -= avail;
+        s->bytes_played += avail;
+
+        /*
+         * We want to free the now-empty buffer, but not if it's also the
+         * current tail. If it is the tail, we don't have enough data to fill
+         * the destination buffer, so we write less and give up.
+         */
+        next = s->bl_head->next;
+        if (next == NULL) {
+#ifdef TIMING_TRACE
+          printf("!");  /* not enough audio data */
+#endif
+          bytes = bytes-bytes_to_copy;
+          break;
+        }
+        free(s->bl_head);
+        s->bl_head = next;
+        s->n_bufs--;
+
+      } /* if (avail >= bytes_to_copy), else */
+
+    } /* while (1) */
+
+    pthread_mutex_unlock(&s->mutex);
+
+    if(bytes > 0) {
+      frames = write(s->output_fd, buffer, bytes);
+      if (frames < 0) {
+          printf("error writing to sound device\n");
+      }
+      if (frames >= 0 && frames != bytes) {
+         printf("short write (expected %d, wrote %d)\n", (int)bytes, (int)frames);
+      }
+    }
+  }
+  free(buffer);
+}
+
+
+
+/*
+ * -----------------------------------------------------------------------------
+ * General query and support functions
+ * -----------------------------------------------------------------------------
+ */
+
+int
+sa_stream_get_write_size(sa_stream_t *s, size_t *size) {
+  sa_buf  * b;
+  size_t    used = 0;
+
+  if (s == NULL || s->output_unit == NULL) {
+    return SA_ERROR_NO_INIT;
+  }
+
+  pthread_mutex_lock(&s->mutex);
+
+  /*
+   * Sum up the used portions of our buffers and subtract that from
+   * the pre-defined max allowed allocation.
+   */
+  for (b = s->bl_head; b != NULL; b = b->next) {
+    used += b->end - b->start;
+  }
+  *size = BUF_SIZE * BUF_LIMIT - used;
+
+  pthread_mutex_unlock(&s->mutex);
+  return SA_SUCCESS;
+}
+
+
+int
+sa_stream_get_position(sa_stream_t *s, sa_position_t position, int64_t *pos) {
+   int err;
+   count_info ptr;
+
+  if (s == NULL || s->output_unit == NULL) {
+    return SA_ERROR_NO_INIT;
+  }
+  if (position != SA_POSITION_WRITE_SOFTWARE) {
+    return SA_ERROR_NOT_SUPPORTED;
+  }
+  if ((err = ioctl(s->output_fd, 
+                       SNDCTL_DSP_GETOPTR, 
+                       &ptr)) <0) {
+      fprintf(stderr, "Error reading playback position\n");
+      return SA_ERROR_OOM;
+  }
+
+  pthread_mutex_lock(&s->mutex);
+  *pos = (int64_t)ptr.bytes;
+  pthread_mutex_unlock(&s->mutex);
+  return SA_SUCCESS;
+}
+
+
+int
+sa_stream_pause(sa_stream_t *s) {
+
+  if (s == NULL || s->output_unit == NULL) {
+    return SA_ERROR_NO_INIT;
+  }
+
+  pthread_mutex_lock(&s->mutex);
+#if 0 /* TODO */
+  AudioOutputUnitStop(s->output_unit);
+#endif
+  pthread_mutex_unlock(&s->mutex);
+  return SA_SUCCESS;
+}
+
+
+int
+sa_stream_resume(sa_stream_t *s) {
+
+  if (s == NULL || s->output_unit == NULL) {
+    return SA_ERROR_NO_INIT;
+  }
+
+  pthread_mutex_lock(&s->mutex);
+
+  /*
+   * The audio device resets its mSampleTime counter after pausing,
+   * so we need to clear our tracking value to keep that in sync.
+   */
+  s->bytes_played = 0;
+#if 0 /* TODO */
+  AudioOutputUnitStart(s->output_unit);
+#endif
+  pthread_mutex_unlock(&s->mutex);
+  return SA_SUCCESS;
+}
+
+
+static sa_buf *
+new_buffer(void) {
+  sa_buf  * b = malloc(sizeof(sa_buf) + BUF_SIZE);
+  if (b != NULL) {
+    b->size  = BUF_SIZE;
+    b->start = 0;
+    b->end   = 0;
+    b->next  = NULL;
+  }
+  return b;
+}
+
+
+
+/*
+ * -----------------------------------------------------------------------------
+ * Extension functions
+ * -----------------------------------------------------------------------------
+ */
+
+int
+sa_stream_set_volume_abs(sa_stream_t *s, float vol) {
+  if (s == NULL || s->output_fd == -1) {
+    return SA_ERROR_NO_INIT;
+  }
+#if SOUND_VERSION >= OSS_VERSION(4,0,0)
+  int mvol = ((int)(100*vol)) | ((int)(100*vol) << 8);
+  if (ioctl(s->output_fd, SNDCTL_DSP_SETPLAYVOL, &mvol) < 0){
+    return SA_ERROR_SYSTEM;
+  }
+  return SA_SUCCESS;
+#else
+  return SA_ERROR_NOT_SUPPORTED;
+#endif
+}
+
+
+int
+sa_stream_get_volume_abs(sa_stream_t *s, float *vol) {
+
+  if (vol == NULL) {
+    return SA_ERROR_INVALID;
+  }
+  *vol = 0.0f;
+  if (s == NULL || s->output_fd == -1) {
+    return SA_ERROR_NO_INIT;
+  }
+#if SOUND_VERSION >= OSS_VERSION(4,0,0)
+  int mvol;
+  if (ioctl(s->output_fd, SNDCTL_DSP_SETPLAYVOL, &mvol) < 0){
+    return SA_ERROR_SYSTEM;
+  }
+  *vol = ((mvol & 0xFF) + (mvol >> 8)) / 200.0f;
+  return SA_SUCCESS;
+#else
+  return SA_ERROR_NOT_SUPPORTED;
+#endif
+}
+
+
+
+/*
+ * -----------------------------------------------------------------------------
+ * Unsupported functions
+ * -----------------------------------------------------------------------------
+ */
+#define UNSUPPORTED(func)   func { return SA_ERROR_NOT_SUPPORTED; }
+
+UNSUPPORTED(int sa_stream_create_opaque(sa_stream_t **s, const char *client_name, sa_mode_t mode, const char *codec))
+UNSUPPORTED(int sa_stream_set_write_lower_watermark(sa_stream_t *s, size_t size))
+UNSUPPORTED(int sa_stream_set_read_lower_watermark(sa_stream_t *s, size_t size))
+UNSUPPORTED(int sa_stream_set_write_upper_watermark(sa_stream_t *s, size_t size))
+UNSUPPORTED(int sa_stream_set_read_upper_watermark(sa_stream_t *s, size_t size))
+UNSUPPORTED(int sa_stream_set_channel_map(sa_stream_t *s, const sa_channel_t map[], unsigned int n))
+UNSUPPORTED(int sa_stream_set_xrun_mode(sa_stream_t *s, sa_xrun_mode_t mode))
+UNSUPPORTED(int sa_stream_set_non_interleaved(sa_stream_t *s, int enable))
+UNSUPPORTED(int sa_stream_set_dynamic_rate(sa_stream_t *s, int enable))
+UNSUPPORTED(int sa_stream_set_driver(sa_stream_t *s, const char *driver))
+UNSUPPORTED(int sa_stream_start_thread(sa_stream_t *s, sa_event_callback_t callback))
+UNSUPPORTED(int sa_stream_stop_thread(sa_stream_t *s))
+UNSUPPORTED(int sa_stream_change_device(sa_stream_t *s, const char *device_name))
+UNSUPPORTED(int sa_stream_change_read_volume(sa_stream_t *s, const int32_t vol[], unsigned int n))
+UNSUPPORTED(int sa_stream_change_write_volume(sa_stream_t *s, const int32_t vol[], unsigned int n))
+UNSUPPORTED(int sa_stream_change_rate(sa_stream_t *s, unsigned int rate))
+UNSUPPORTED(int sa_stream_change_meta_data(sa_stream_t *s, const char *name, const void *data, size_t size))
+UNSUPPORTED(int sa_stream_change_user_data(sa_stream_t *s, const void *value))
+UNSUPPORTED(int sa_stream_set_adjust_rate(sa_stream_t *s, sa_adjust_t direction))
+UNSUPPORTED(int sa_stream_set_adjust_nchannels(sa_stream_t *s, sa_adjust_t direction))
+UNSUPPORTED(int sa_stream_set_adjust_pcm_format(sa_stream_t *s, sa_adjust_t direction))
+UNSUPPORTED(int sa_stream_set_adjust_watermarks(sa_stream_t *s, sa_adjust_t direction))
+UNSUPPORTED(int sa_stream_get_mode(sa_stream_t *s, sa_mode_t *access_mode))
+UNSUPPORTED(int sa_stream_get_codec(sa_stream_t *s, char *codec, size_t *size))
+UNSUPPORTED(int sa_stream_get_pcm_format(sa_stream_t *s, sa_pcm_format_t *format))
+UNSUPPORTED(int sa_stream_get_rate(sa_stream_t *s, unsigned int *rate))
+UNSUPPORTED(int sa_stream_get_nchannels(sa_stream_t *s, int *nchannels))
+UNSUPPORTED(int sa_stream_get_user_data(sa_stream_t *s, void **value))
+UNSUPPORTED(int sa_stream_get_write_lower_watermark(sa_stream_t *s, size_t *size))
+UNSUPPORTED(int sa_stream_get_read_lower_watermark(sa_stream_t *s, size_t *size))
+UNSUPPORTED(int sa_stream_get_write_upper_watermark(sa_stream_t *s, size_t *size))
+UNSUPPORTED(int sa_stream_get_read_upper_watermark(sa_stream_t *s, size_t *size))
+UNSUPPORTED(int sa_stream_get_channel_map(sa_stream_t *s, sa_channel_t map[], unsigned int *n))
+UNSUPPORTED(int sa_stream_get_xrun_mode(sa_stream_t *s, sa_xrun_mode_t *mode))
+UNSUPPORTED(int sa_stream_get_non_interleaved(sa_stream_t *s, int *enabled))
+UNSUPPORTED(int sa_stream_get_dynamic_rate(sa_stream_t *s, int *enabled))
+UNSUPPORTED(int sa_stream_get_driver(sa_stream_t *s, char *driver_name, size_t *size))
+UNSUPPORTED(int sa_stream_get_device(sa_stream_t *s, char *device_name, size_t *size))
+UNSUPPORTED(int sa_stream_get_read_volume(sa_stream_t *s, int32_t vol[], unsigned int *n))
+UNSUPPORTED(int sa_stream_get_write_volume(sa_stream_t *s, int32_t vol[], unsigned int *n))
+UNSUPPORTED(int sa_stream_get_meta_data(sa_stream_t *s, const char *name, void*data, size_t *size))
+UNSUPPORTED(int sa_stream_get_adjust_rate(sa_stream_t *s, sa_adjust_t *direction))
+UNSUPPORTED(int sa_stream_get_adjust_nchannels(sa_stream_t *s, sa_adjust_t *direction))
+UNSUPPORTED(int sa_stream_get_adjust_pcm_format(sa_stream_t *s, sa_adjust_t *direction))
+UNSUPPORTED(int sa_stream_get_adjust_watermarks(sa_stream_t *s, sa_adjust_t *direction))
+UNSUPPORTED(int sa_stream_get_state(sa_stream_t *s, sa_state_t *state))
+UNSUPPORTED(int sa_stream_get_event_error(sa_stream_t *s, sa_error_t *error))
+UNSUPPORTED(int sa_stream_get_event_notify(sa_stream_t *s, sa_notify_t *notify))
+UNSUPPORTED(int sa_stream_read(sa_stream_t *s, void *data, size_t nbytes))
+UNSUPPORTED(int sa_stream_read_ni(sa_stream_t *s, unsigned int channel, void *data, size_t nbytes))
+UNSUPPORTED(int sa_stream_write_ni(sa_stream_t *s, unsigned int channel, const void *data, size_t nbytes))
+UNSUPPORTED(int sa_stream_pwrite(sa_stream_t *s, const void *data, size_t nbytes, int64_t offset, sa_seek_t whence))
+UNSUPPORTED(int sa_stream_pwrite_ni(sa_stream_t *s, unsigned int channel, const void *data, size_t nbytes, int64_t offset, sa_seek_t whence))
+UNSUPPORTED(int sa_stream_get_read_size(sa_stream_t *s, size_t *size))
+UNSUPPORTED(int sa_stream_drain(sa_stream_t *s))
+
+const char *sa_strerror(int code) { return NULL; }
+
+#endif
new file mode 100644
--- /dev/null
+++ b/media/libsydneyaudio/src/sydney_audio_pulseaudio.c
@@ -0,0 +1,707 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** *
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <pthread.h>
+#include <pulse/pulseaudio.h>
+#include "sydney_audio.h"
+
+/* Pulseaudio implementation based heavily on sydney_audio_alsa.c */
+
+/*
+ * The audio interface is based on a "pull" I/O model, which means you
+ * can't just provide a data buffer and tell the audio device to play; you must
+ * register a callback and provide data as the device asks for it. To support
+ * sydney audio's "write-to-play" style interface, we have to buffer up the
+ * data as it arrives and feed it to the callback as required.
+ *
+ * This is handled by a simple linked list of buffers; data is always written
+ * to the tail and read from the head. Each buffer tracks the start and end
+ * positions of its contained data. Buffers are allocated when the tail buffer
+ * fills, and freed when the head buffer empties. There is always at least one
+ * buffer allocated.
+ *
+ *       s   e      s      e      s  e            + data read
+ *    +++#####  ->  ########  ->  ####----        # data written
+ *    ^                           ^               - empty
+ *    bl_head                     bl_tail
+ */
+
+typedef struct sa_buf sa_buf;
+struct sa_buf {
+  unsigned int      size;
+  unsigned int      start;
+  unsigned int      end;
+  sa_buf          * next;
+  unsigned char     data[0];
+};
+
+struct sa_stream {
+  pa_context*       context;
+  pa_stream*        stream;
+  pa_sample_spec    sample_spec;
+  pa_threaded_mainloop* m;
+
+  pthread_t         thread_id;
+  pthread_mutex_t   mutex;
+
+  char              playing;
+  int64_t           bytes_written;
+  char              client_name[255];
+
+  /* buffer list */
+  sa_buf          * bl_head;
+  sa_buf          * bl_tail;
+  int               n_bufs;
+};
+
+
+/*
+ * Use a default buffer size with enough room for one second of audio,
+ * assuming stereo data at 44.1kHz with 32 bits per channel, and impose
+ * a generous limit on the number of buffers.
+ */
+#define BUF_SIZE    (2 * 44100 * 4)
+#define BUF_LIMIT   5
+
+#if BUF_LIMIT < 2
+#error BUF_LIMIT must be at least 2!
+#endif
+
+static void audio_callback(void* data);
+static void stream_write_callback(pa_stream *stream, size_t length, void *userdata);
+static void stream_latency_update_callback(pa_stream *stream, void *userdata);
+static void context_state_callback(pa_context *c, void *userdata);
+static sa_buf *new_buffer(void);
+
+
+
+/*
+ * -----------------------------------------------------------------------------
+ * Pulseaudio callback functions
+ * -----------------------------------------------------------------------------
+ */
+ 
+static void context_state_callback(pa_context *c, void *userdata) {
+  sa_stream_t* s = (sa_stream_t*)userdata;
+  switch (pa_context_get_state(c)) {
+    case PA_CONTEXT_READY:
+    case PA_CONTEXT_TERMINATED:
+    case PA_CONTEXT_FAILED:
+      pa_threaded_mainloop_signal(s->m, 0);
+      break;
+    case PA_CONTEXT_UNCONNECTED:
+    case PA_CONTEXT_CONNECTING:
+    case PA_CONTEXT_AUTHORIZING:
+    case PA_CONTEXT_SETTING_NAME:
+      break;
+  }
+}
+
+static void stream_state_callback(pa_stream *stream, void *userdata) {
+  sa_stream_t* s = (sa_stream_t*)userdata;
+  switch (pa_stream_get_state(stream)) {
+
+      case PA_STREAM_READY:
+      case PA_STREAM_FAILED:
+      case PA_STREAM_TERMINATED:
+        pa_threaded_mainloop_signal(s->m, 0);
+        break;
+      case PA_STREAM_UNCONNECTED:
+      case PA_STREAM_CREATING:
+        break;
+  }
+}
+
+static void stream_write_callback(pa_stream *stream, size_t length, void *userdata)
+{
+  sa_stream_t* s = (sa_stream_t*)userdata;
+  pa_threaded_mainloop_signal(s->m, 0);
+}
+
+static void stream_latency_update_callback(pa_stream *stream, void *userdata)
+{
+  sa_stream_t* s = (sa_stream_t*)userdata;
+  pa_threaded_mainloop_signal(s->m, 0);
+}
+
+
+
+/*
+ * -----------------------------------------------------------------------------
+ * Startup and shutdown functions
+ * -----------------------------------------------------------------------------
+ */
+
+int
+sa_stream_create_pcm(
+  sa_stream_t      ** _s,
+  const char        * client_name,
+  sa_mode_t           mode,
+  sa_pcm_format_t     format,
+  unsigned  int       rate,
+  unsigned  int       n_channels
+) {
+  sa_stream_t   * s = 0;
+  char *server = NULL;
+
+  /*
+   * Make sure we return a NULL stream pointer on failure.
+   */
+  if (_s == NULL) {
+    return SA_ERROR_INVALID;
+  }
+  *_s = NULL;
+
+  if (mode != SA_MODE_WRONLY) {
+    return SA_ERROR_NOT_SUPPORTED;
+  }
+  if (format != SA_PCM_FORMAT_S16_LE) {
+    return SA_ERROR_NOT_SUPPORTED;
+  }
+
+  /*
+   * Allocate the instance and required resources.
+   */
+  if ((s = malloc(sizeof(sa_stream_t))) == NULL) {
+    return SA_ERROR_OOM;
+  }
+  if ((s->bl_head = new_buffer()) == NULL) {
+    free(s);
+    return SA_ERROR_OOM;
+  }
+
+  if (pthread_mutex_init(&s->mutex, NULL) != 0) {
+    free(s->bl_head);
+    free(s);
+    return SA_ERROR_SYSTEM;
+  }
+
+  s->stream        = NULL;
+  s->m             = NULL;
+  s->thread_id     = 0;
+  s->playing       = 0;
+  s->bytes_written = 0;
+
+  s->bl_tail       = s->bl_head;
+  s->n_bufs        = 1;
+
+  s->sample_spec.format = PA_SAMPLE_S16LE;
+  s->sample_spec.channels = n_channels;
+  s->sample_spec.rate = rate;
+
+  strcpy(s->client_name, client_name);
+
+  /* Set up a new main loop */
+  s->m = pa_threaded_mainloop_new();
+  pa_threaded_mainloop_start(s->m);
+
+  pa_threaded_mainloop_lock(s->m);
+
+  /* Create a new connection context */
+  if (!(s->context = pa_context_new(pa_threaded_mainloop_get_api(s->m), "OggPlay"))) {
+    fprintf(stderr, "pa_context_new() failed.\n");
+    goto unlock_and_fail;
+  }
+  pa_context_set_state_callback(s->context, context_state_callback, s);
+
+  pa_context_connect(s->context, server, 0, NULL);
+
+  /* Wait until the context is ready */
+  pa_threaded_mainloop_wait(s->m);
+  if (pa_context_get_state(s->context) != PA_CONTEXT_READY) {
+    fprintf(stderr, "creating Pulseaudio Context failed\n");
+    goto unlock_and_fail;
+  }
+  pa_threaded_mainloop_unlock(s->m);
+
+  *_s = s;
+  return SA_SUCCESS;
+
+unlock_and_fail:
+  pa_threaded_mainloop_unlock(s->m);
+  free(s);
+  return SA_ERROR_OOM;
+}
+
+int
+sa_stream_open(sa_stream_t *s) {
+  if (s == NULL) {
+    return SA_ERROR_NO_INIT;
+  }
+  if (s->stream != NULL) {
+    return SA_ERROR_INVALID;
+  }
+
+  pa_threaded_mainloop_lock(s->m);
+  if (!(s->stream = pa_stream_new(s->context, s->client_name, &s->sample_spec, NULL))) {
+    fprintf(stderr, "pa_stream_new() failed: %s\n", pa_strerror(pa_context_errno(s->context)));
+    goto unlock_and_fail;
+  }
+
+  pa_stream_set_state_callback(s->stream, stream_state_callback, s);
+  pa_stream_set_write_callback(s->stream, stream_write_callback, s);
+  pa_stream_set_latency_update_callback(s->stream, stream_latency_update_callback, s);
+
+  if (pa_stream_connect_playback(s->stream, NULL, NULL, 0, NULL, NULL) < 0) {
+    fprintf(stderr, "pa_stream_connect_playback() failed: %s\n", pa_strerror(pa_context_errno(s->context)));
+    goto unlock_and_fail;
+  }
+
+  /* Wait until the stream is ready */
+  pa_threaded_mainloop_wait(s->m);
+
+  if (pa_stream_get_state(s->stream) != PA_STREAM_READY) {
+    fprintf(stderr, "Failed to connect stream: %s", pa_strerror(pa_context_errno(s->context)));
+    goto unlock_and_fail;
+  }
+  pa_threaded_mainloop_unlock(s->m);
+
+  if (!s->stream)
+    return SA_ERROR_NO_DEVICE;
+  return SA_SUCCESS;
+
+unlock_and_fail:
+  pa_threaded_mainloop_unlock(s->m);
+  return SA_ERROR_NO_DEVICE;
+}
+
+int
+sa_stream_destroy(sa_stream_t *s) {
+  if (s == NULL) {
+    return SA_SUCCESS;
+  }
+
+  pthread_mutex_lock(&s->mutex);
+  s->thread_id = 0;
+  pthread_mutex_unlock(&s->mutex);
+
+  pa_threaded_mainloop_lock(s->m);
+  pa_stream_disconnect(s->stream);
+  s->stream = NULL;
+  pa_context_disconnect(s->context);
+  pa_context_unref(s->context);
+  s->context = NULL;
+  pa_threaded_mainloop_unlock(s->m);
+
+  pa_threaded_mainloop_stop(s->m);
+  pa_threaded_mainloop_free(s->m);
+
+  pthread_mutex_destroy(&s->mutex);
+
+  while (s->bl_head != NULL) {
+    sa_buf  * next = s->bl_head->next;
+    free(s->bl_head);
+    s->bl_head = next;
+  }
+  free(s);
+
+  return SA_SUCCESS;
+}
+
+
+
+/*
+ * -----------------------------------------------------------------------------
+ * Data read and write functions
+ * -----------------------------------------------------------------------------
+ */
+
+int
+sa_stream_write(sa_stream_t *s, const void *data, size_t nbytes) {
+  int result = SA_SUCCESS;
+
+  if (s == NULL || s->stream == NULL) {
+    return SA_ERROR_NO_INIT;
+  }
+  if (nbytes == 0) {
+    return SA_SUCCESS;
+  }
+
+  pthread_mutex_lock(&s->mutex);
+
+  /*
+   * Append the new data to the end of our buffer list.
+   */
+  while (1) {
+    unsigned int avail = s->bl_tail->size - s->bl_tail->end;
+
+    if (nbytes <= avail) {
+
+      /*
+       * The new data will fit into the current tail buffer, so
+       * just copy it in and we're done.
+       */
+      memcpy(s->bl_tail->data + s->bl_tail->end, data, nbytes);
+      s->bl_tail->end += nbytes;
+      break;
+
+    } else {
+
+      /*
+       * Copy what we can into the tail and allocate a new buffer
+       * for the rest.
+       */
+      memcpy(s->bl_tail->data + s->bl_tail->end, data, avail);
+      s->bl_tail->end += avail;
+      data = ((unsigned char *)data) + avail;
+      nbytes -= avail;
+
+      /* 
+       * If we still have data left to copy but we've hit the limit of
+       * allowable buffer allocations, we need to spin for a bit to allow
+       * the audio callback function to slurp some more data up.
+       */
+      if (nbytes > 0 && s->n_bufs == BUF_LIMIT) {
+        if (!s->playing) {
+          /*
+           * We haven't even started playing yet! That means the
+           * BUF_SIZE/BUF_LIMIT values are too low... Not much we can
+           * do here; spinning won't help because the audio callback
+           * hasn't been enabled yet. Oh well, error time.
+           */
+          printf("Too much audio data received before audio device enabled!\n");
+          result = SA_ERROR_SYSTEM;
+          break;
+        }
+        while (s->n_bufs == BUF_LIMIT) {
+          struct timespec ts = {0, 1000000};
+          pthread_mutex_unlock(&s->mutex);
+          nanosleep(&ts, NULL);
+          pthread_mutex_lock(&s->mutex);
+        }
+      }
+
+      /* 
+       * Allocate a new tail buffer, and go 'round again to fill it up.
+       */
+      if ((s->bl_tail->next = new_buffer()) == NULL) {
+        result = SA_ERROR_OOM;
+        break;
+      }
+      s->n_bufs++;
+      s->bl_tail = s->bl_tail->next;
+    
+    } /* if (nbytes <= avail), else */
+
+  } /* while (1) */
+  pthread_mutex_unlock(&s->mutex);
+  /*
+   * Once we have our first block of audio data, enable the audio callback
+   * function. This doesn't need to be protected by the mutex, because
+   * s->playing is not used in the audio callback thread, and it's probably
+   * better not to be inside the lock when we enable the audio callback.
+   */
+  if (!s->playing) {
+    s->playing = 1;
+    if (pthread_create(&s->thread_id, NULL, (void *)audio_callback, s) != 0) {
+      result = SA_ERROR_SYSTEM;
+    }
+  }
+  return result;
+}
+
+static void audio_callback(void* data)
+{
+  sa_stream_t* s = (sa_stream_t*)data;
+  unsigned int bytes_per_frame = s->sample_spec.channels * pa_sample_size(&s->sample_spec);
+  size_t buffer_size = s->sample_spec.rate * bytes_per_frame;
+  char* buffer = malloc(buffer_size);
+
+  while(1) {
+    char* dst = buffer;
+    size_t bytes_to_copy, bytes;
+
+    pa_threaded_mainloop_lock(s->m);
+    while(1) {
+      if (s == NULL || s->stream == NULL) {
+        if (s != NULL && s->m != NULL) 
+          pa_threaded_mainloop_unlock(s->m);
+        goto free_buffer;
+      }
+      if ((bytes_to_copy = pa_stream_writable_size(s->stream)) == (size_t) -1) {
+        fprintf(stderr, "pa_stream_writable_size() failed: %s", pa_strerror(pa_context_errno(s->context)));
+        pa_threaded_mainloop_unlock(s->m);
+        goto free_buffer;
+      }
+      if(bytes_to_copy > 0)
+        break;
+      pa_threaded_mainloop_wait(s->m);
+    }
+    pa_threaded_mainloop_unlock(s->m);
+    if (bytes_to_copy > buffer_size)
+      bytes_to_copy = buffer_size;
+    bytes = bytes_to_copy;
+
+    pthread_mutex_lock(&s->mutex);
+    if (!s->thread_id) {
+      pthread_mutex_unlock(&s->mutex);
+      break;
+    }
+    /*
+     * Consume data from the start of the buffer list.
+     */
+    while (1) {
+      unsigned int avail = s->bl_head->end - s->bl_head->start;
+      assert(s->bl_head->start <= s->bl_head->end);
+
+      if (avail >= bytes_to_copy) {
+        /*
+         * We have all we need in the head buffer, so just grab it and go.
+         */
+        memcpy(dst, s->bl_head->data + s->bl_head->start, bytes_to_copy);
+        s->bl_head->start += bytes_to_copy;
+        break;
+    
+      } else {
+        sa_buf* next = 0;
+        /*
+         * Copy what we can from the head and move on to the next buffer.
+         */
+        memcpy(dst, s->bl_head->data + s->bl_head->start, avail);
+        s->bl_head->start += avail;
+        dst += avail;
+        bytes_to_copy -= avail;
+        /*
+         * We want to free the now-empty buffer, but not if it's also the
+         * current tail. If it is the tail, we don't have enough data to fill
+         * the destination buffer, so we write less and give up.
+         */
+        next = s->bl_head->next;
+        if (next == NULL) {
+          bytes = bytes-bytes_to_copy;
+          break;
+        }
+        free(s->bl_head);
+        s->bl_head = next;
+        s->n_bufs--;
+      } /* if (avail >= bytes_to_copy), else */
+    } /* while (1) */
+
+    if(bytes > 0) {
+      pa_threaded_mainloop_lock(s->m);
+      if (pa_stream_write(s->stream, buffer, bytes, NULL, 0, PA_SEEK_RELATIVE) < 0) {
+        fprintf(stderr, "pa_stream_write() failed: %s", pa_strerror(pa_context_errno(s->context)));
+        pa_threaded_mainloop_unlock(s->m);
+        return;
+      }
+      pa_stream_update_timing_info(s->stream, NULL, NULL);
+      s->bytes_written += bytes;
+      pa_threaded_mainloop_unlock(s->m);
+    }
+    pthread_mutex_unlock(&s->mutex);
+  }
+free_buffer:
+  free(buffer);
+}
+
+
+/*
+ * -----------------------------------------------------------------------------
+ * General query and support functions
+ * -----------------------------------------------------------------------------
+ */
+
+
+int
+sa_stream_get_write_size(sa_stream_t *s, size_t *size) {
+  sa_buf  * b;
+  size_t    used = 0;
+
+  if (s == NULL || s->stream == NULL) {
+    return SA_ERROR_NO_INIT;
+  }
+
+  pthread_mutex_lock(&s->mutex);
+
+  /*
+   * Sum up the used portions of our buffers and subtract that from
+   * the pre-defined max allowed allocation.
+   */
+  for (b = s->bl_head; b != NULL; b = b->next) {
+    used += b->end - b->start;
+  }
+  *size = BUF_SIZE * BUF_LIMIT - used;
+
+  pthread_mutex_unlock(&s->mutex);
+  return SA_SUCCESS;
+}
+
+
+int
+sa_stream_get_position(sa_stream_t *s, sa_position_t position, int64_t *pos) {
+  pa_usec_t usec;
+  if (s == NULL || s->stream == NULL) {
+    return SA_ERROR_NO_INIT;
+  }
+  if (position != SA_POSITION_WRITE_SOFTWARE) {
+    return SA_ERROR_NOT_SUPPORTED;
+  }
+  pa_threaded_mainloop_lock(s->m);
+  if(pa_stream_get_time(s->stream,  &usec) != PA_ERR_NODATA) {
+    *pos = pa_usec_to_bytes(usec, &s->sample_spec);
+  }
+  else {
+    *pos  = s->bytes_written;
+  }
+  pa_threaded_mainloop_unlock(s->m);
+  return SA_SUCCESS;
+}
+
+
+int
+sa_stream_pause(sa_stream_t *s) {
+  if (s == NULL || s->stream == NULL) {
+    return SA_ERROR_NO_INIT;
+  }
+  return SA_SUCCESS;
+}
+
+
+int
+sa_stream_resume(sa_stream_t *s) {
+  if (s == NULL || s->stream == NULL) {
+    return SA_ERROR_NO_INIT;
+  }
+
+  pa_threaded_mainloop_lock(s->m);
+  s->bytes_written = 0;
+  pa_threaded_mainloop_unlock(s->m);
+  return SA_SUCCESS;
+}
+
+
+static sa_buf *
+new_buffer(void) {
+  sa_buf  * b = malloc(sizeof(sa_buf) + BUF_SIZE);
+  if (b != NULL) {
+    b->size  = BUF_SIZE;
+    b->start = 0;
+    b->end   = 0;
+    b->next  = NULL;
+  }
+  return b;
+}
+
+
+
+/*
+ * -----------------------------------------------------------------------------
+ * Extension functions
+ * -----------------------------------------------------------------------------
+ */
+
+int
+sa_stream_set_volume_abs(sa_stream_t *s, float vol) {
+  pa_cvolume cv;
+
+  if (s == NULL || s->stream == NULL) {
+    return SA_ERROR_NO_INIT;
+  }
+  pa_cvolume_set(&cv, s->sample_spec.channels, pa_sw_volume_from_dB(vol));
+
+  return SA_SUCCESS;
+}
+
+
+int
+sa_stream_get_volume_abs(sa_stream_t *s, float *vol) {
+  if (s == NULL || s->stream == NULL) {
+    return SA_ERROR_NO_INIT;
+  }
+  printf("sa_stream_get_volume_abs not implemented\n");
+  return SA_SUCCESS;
+}
+
+
+/*
+ * -----------------------------------------------------------------------------
+ * Unsupported functions
+ * -----------------------------------------------------------------------------
+ */
+#define UNSUPPORTED(func)   func { return SA_ERROR_NOT_SUPPORTED; }
+
+UNSUPPORTED(int sa_stream_create_opaque(sa_stream_t **s, const char *client_name, sa_mode_t mode, const char *codec))
+UNSUPPORTED(int sa_stream_set_write_lower_watermark(sa_stream_t *s, size_t size))
+UNSUPPORTED(int sa_stream_set_read_lower_watermark(sa_stream_t *s, size_t size))
+UNSUPPORTED(int sa_stream_set_write_upper_watermark(sa_stream_t *s, size_t size))
+UNSUPPORTED(int sa_stream_set_read_upper_watermark(sa_stream_t *s, size_t size))
+UNSUPPORTED(int sa_stream_set_channel_map(sa_stream_t *s, const sa_channel_t map[], unsigned int n))
+UNSUPPORTED(int sa_stream_set_xrun_mode(sa_stream_t *s, sa_xrun_mode_t mode))
+UNSUPPORTED(int sa_stream_set_non_interleaved(sa_stream_t *s, int enable))
+UNSUPPORTED(int sa_stream_set_dynamic_rate(sa_stream_t *s, int enable))
+UNSUPPORTED(int sa_stream_set_driver(sa_stream_t *s, const char *driver))
+UNSUPPORTED(int sa_stream_start_thread(sa_stream_t *s, sa_event_callback_t callback))
+UNSUPPORTED(int sa_stream_stop_thread(sa_stream_t *s))
+UNSUPPORTED(int sa_stream_change_device(sa_stream_t *s, const char *device_name))
+UNSUPPORTED(int sa_stream_change_read_volume(sa_stream_t *s, const int32_t vol[], unsigned int n))
+UNSUPPORTED(int sa_stream_change_write_volume(sa_stream_t *s, const int32_t vol[], unsigned int n))
+UNSUPPORTED(int sa_stream_change_rate(sa_stream_t *s, unsigned int rate))
+UNSUPPORTED(int sa_stream_change_meta_data(sa_stream_t *s, const char *name, const void *data, size_t size))
+UNSUPPORTED(int sa_stream_change_user_data(sa_stream_t *s, const void *value))
+UNSUPPORTED(int sa_stream_set_adjust_rate(sa_stream_t *s, sa_adjust_t direction))
+UNSUPPORTED(int sa_stream_set_adjust_nchannels(sa_stream_t *s, sa_adjust_t direction))
+UNSUPPORTED(int sa_stream_set_adjust_pcm_format(sa_stream_t *s, sa_adjust_t direction))
+UNSUPPORTED(int sa_stream_set_adjust_watermarks(sa_stream_t *s, sa_adjust_t direction))
+UNSUPPORTED(int sa_stream_get_mode(sa_stream_t *s, sa_mode_t *access_mode))
+UNSUPPORTED(int sa_stream_get_codec(sa_stream_t *s, char *codec, size_t *size))
+UNSUPPORTED(int sa_stream_get_pcm_format(sa_stream_t *s, sa_pcm_format_t *format))
+UNSUPPORTED(int sa_stream_get_rate(sa_stream_t *s, unsigned int *rate))
+UNSUPPORTED(int sa_stream_get_nchannels(sa_stream_t *s, int *nchannels))
+UNSUPPORTED(int sa_stream_get_user_data(sa_stream_t *s, void **value))
+UNSUPPORTED(int sa_stream_get_write_lower_watermark(sa_stream_t *s, size_t *size))
+UNSUPPORTED(int sa_stream_get_read_lower_watermark(sa_stream_t *s, size_t *size))
+UNSUPPORTED(int sa_stream_get_write_upper_watermark(sa_stream_t *s, size_t *size))
+UNSUPPORTED(int sa_stream_get_read_upper_watermark(sa_stream_t *s, size_t *size))
+UNSUPPORTED(int sa_stream_get_channel_map(sa_stream_t *s, sa_channel_t map[], unsigned int *n))
+UNSUPPORTED(int sa_stream_get_xrun_mode(sa_stream_t *s, sa_xrun_mode_t *mode))
+UNSUPPORTED(int sa_stream_get_non_interleaved(sa_stream_t *s, int *enabled))
+UNSUPPORTED(int sa_stream_get_dynamic_rate(sa_stream_t *s, int *enabled))
+UNSUPPORTED(int sa_stream_get_driver(sa_stream_t *s, char *driver_name, size_t *size))
+UNSUPPORTED(int sa_stream_get_device(sa_stream_t *s, char *device_name, size_t *size))
+UNSUPPORTED(int sa_stream_get_read_volume(sa_stream_t *s, int32_t vol[], unsigned int *n))
+UNSUPPORTED(int sa_stream_get_write_volume(sa_stream_t *s, int32_t vol[], unsigned int *n))
+UNSUPPORTED(int sa_stream_get_meta_data(sa_stream_t *s, const char *name, void*data, size_t *size))
+UNSUPPORTED(int sa_stream_get_adjust_rate(sa_stream_t *s, sa_adjust_t *direction))
+UNSUPPORTED(int sa_stream_get_adjust_nchannels(sa_stream_t *s, sa_adjust_t *direction))
+UNSUPPORTED(int sa_stream_get_adjust_pcm_format(sa_stream_t *s, sa_adjust_t *direction))
+UNSUPPORTED(int sa_stream_get_adjust_watermarks(sa_stream_t *s, sa_adjust_t *direction))
+UNSUPPORTED(int sa_stream_get_state(sa_stream_t *s, sa_state_t *state))
+UNSUPPORTED(int sa_stream_get_event_error(sa_stream_t *s, sa_error_t *error))
+UNSUPPORTED(int sa_stream_get_event_notify(sa_stream_t *s, sa_notify_t *notify))
+UNSUPPORTED(int sa_stream_read(sa_stream_t *s, void *data, size_t nbytes))
+UNSUPPORTED(int sa_stream_read_ni(sa_stream_t *s, unsigned int channel, void *data, size_t nbytes))
+UNSUPPORTED(int sa_stream_write_ni(sa_stream_t *s, unsigned int channel, const void *data, size_t nbytes))
+UNSUPPORTED(int sa_stream_pwrite(sa_stream_t *s, const void *data, size_t nbytes, int64_t offset, sa_seek_t whence))
+UNSUPPORTED(int sa_stream_pwrite_ni(sa_stream_t *s, unsigned int channel, const void *data, size_t nbytes, int64_t offset, sa_seek_t whence))
+UNSUPPORTED(int sa_stream_get_read_size(sa_stream_t *s, size_t *size))
+UNSUPPORTED(int sa_stream_drain(sa_stream_t *s))
+
+const char *sa_strerror(int code) { return NULL; }
+
new file mode 100644
--- /dev/null
+++ b/media/libsydneyaudio/src/sydney_audio_sunaudio.c
@@ -0,0 +1,407 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Initial Developer of the Original Code is
+ * Copyright (C) 2008 Sun Microsystems, Inc.,
+ *                Brian Lu <brian.lu@sun.com>
+ *
+ * Contributor(s): 
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** *
+ */
+#include <stdlib.h>
+#include <pthread.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stropts.h>
+#include <sys/audio.h>
+#include <sys/mixer.h>
+#include <errno.h>
+#include <stdio.h>
+#include <pthread.h>
+#include "sydney_audio.h"
+
+#define DEFAULT_AUDIO_DEVICE "/dev/audio" 
+
+#define LOOP_WHILE_EINTR(v,func) do { (v) = (func); } \
+                while ((v) == -1 && errno == EINTR);
+
+struct sa_stream 
+{
+  int        audio_fd;
+
+  /* audio format info */
+  /* default setting */
+  unsigned int      default_n_channels;
+  unsigned int      default_rate;
+  unsigned int      default_precision;
+
+  /* used settings */
+  unsigned int      rate;
+  unsigned int      n_channels;
+  unsigned int      precision;
+  int64_t           bytes_played;
+
+};
+
+
+/*
+ * -----------------------------------------------------------------------------
+ * Startup and shutdown functions
+ * -----------------------------------------------------------------------------
+ */
+
+int
+sa_stream_create_pcm(
+  sa_stream_t      ** _s,
+  const char        * client_name,
+  sa_mode_t           mode,
+  sa_pcm_format_t     format,
+  unsigned  int       rate,
+  unsigned  int       n_channels
+) 
+{
+  sa_stream_t   * s = 0;
+
+  /* Make sure we return a NULL stream pointer on failure. */
+  if (_s == NULL) 
+    return SA_ERROR_INVALID;
+
+  *_s = NULL;
+
+  if (mode != SA_MODE_WRONLY) 
+    return SA_ERROR_NOT_SUPPORTED;
+
+  if (format != SA_PCM_FORMAT_S16_LE) 
+    return SA_ERROR_NOT_SUPPORTED;
+
+  /*
+   * Allocate the instance and required resources.
+   */
+  if ((s = malloc(sizeof(sa_stream_t))) == NULL) 
+    return SA_ERROR_OOM;
+
+  s->audio_fd = NULL;
+
+  s->rate = rate;
+  s->n_channels = n_channels;
+  s->precision = 16;
+  s->bytes_played = 0;
+
+  *_s = s;
+
+  return SA_SUCCESS;
+}
+
+
+int
+sa_stream_open(sa_stream_t *s) 
+{
+  int fd,err;
+  audio_info_t audio_info;
+  char *device_name;
+  
+  /* according to the sun audio manual (man audio(7I))
+   * use the device name set in AUDIODEV
+   * environment variaible if it is set 
+   */
+  device_name = getenv("AUDIODEV");
+  if (!device_name)
+    device_name = DEFAULT_AUDIO_DEVICE;
+
+  if (s == NULL) 
+    return SA_ERROR_NO_INIT;
+
+  if (s->audio_fd != NULL) 
+    return SA_ERROR_INVALID;
+
+  fd = open(device_name,O_WRONLY | O_NONBLOCK);
+  if (fd >= 0) 
+  {
+     close (fd);
+     fd = open (device_name, O_WRONLY);
+  }
+
+  if ( fd < 0 )
+  {
+    printf("Open %s failed:%s ",device_name,strerror(errno));
+    return SA_ERROR_NO_DEVICE;
+  }
+  
+  AUDIO_INITINFO(&audio_info);
+
+  // save the default settings for resetting
+  err = ioctl(fd, AUDIO_GETINFO, &audio_info); 
+  if (err == -1)
+  {
+    perror("ioctl AUDIO_GETINFO failed");
+    close(fd);
+    return SA_ERROR_SYSTEM;
+  }
+
+  s->default_n_channels = audio_info.play.channels; 
+  s->default_rate = audio_info.play.sample_rate; 
+  s->default_precision =  audio_info.play.precision; 
+
+  AUDIO_INITINFO(&audio_info)
+
+  audio_info.play.sample_rate = s->rate;
+  audio_info.play.channels = s->n_channels;
+  audio_info.play.precision = s->precision;
+
+  /* Signed Linear PCM encoding */
+  audio_info.play.encoding = AUDIO_ENCODING_LINEAR;
+
+  err=ioctl(fd,AUDIO_SETINFO,&audio_info);
+  if (err== -1)
+    return SA_ERROR_NOT_SUPPORTED;
+
+  AUDIO_INITINFO(&audio_info)
+  err=ioctl(fd,AUDIO_GETINFO,&audio_info);
+  if (err== -1)
+  {
+    perror("ioctl AUDIO_SETINFO failed"); 
+    return SA_ERROR_NOT_SUPPORTED;
+  }
+
+  s->audio_fd = fd;
+
+  return SA_SUCCESS;
+}
+
+int
+sa_stream_destroy(sa_stream_t *s) 
+{
+  int result = SA_SUCCESS;
+
+  if (s == NULL) 
+    return SA_SUCCESS;
+
+  /*
+   * Shut down the audio output device.
+   */
+  if (s->audio_fd != NULL) 
+  {
+    if (close(s->audio_fd) < 0) 
+    {
+      perror("Close sun audio fd failed");
+      result = SA_ERROR_SYSTEM;
+    }
+  }
+
+  free(s);
+
+  return result;
+}
+
+/*
+ * -----------------------------------------------------------------------------
+ * Data read and write functions
+ * -----------------------------------------------------------------------------
+ */
+
+int
+sa_stream_write(sa_stream_t *s, const void *data, size_t nbytes) 
+{
+
+  int result = SA_SUCCESS;
+  int total = 0;
+  int bytes = 0;
+  int fd;
+  int i;
+  audio_info_t ainfo;
+
+  if (s == NULL || s->audio_fd == NULL) 
+    return SA_ERROR_NO_INIT;
+
+  if (nbytes == 0) 
+    return SA_SUCCESS;
+
+  fd = s->audio_fd;
+
+  while (total < nbytes ) 
+  {
+    LOOP_WHILE_EINTR(bytes,(write(fd, (void *)(((unsigned char *)data)  total), nbytes-total)));
+
+    total = bytes;
+    if (total != nbytes)
+      printf("SunAudio\tWrite completed short - %d vs %d. Write more data\n",total,nbytes);
+  }
+
+  s->bytes_played += nbytes;
+
+  return result;
+}
+
+
+
+/*
+ * -----------------------------------------------------------------------------
+ * General query and support functions
+ * -----------------------------------------------------------------------------
+ */
+
+int
+sa_stream_get_position(sa_stream_t *s, sa_position_t position, int64_t *pos) 
+{
+
+  if (s == NULL || s->audio_fd == NULL) 
+    return SA_ERROR_NO_INIT;
+
+  if (position != SA_POSITION_WRITE_SOFTWARE) 
+    return SA_ERROR_NOT_SUPPORTED;
+
+  *pos = s->bytes_played;
+  return SA_SUCCESS;
+}
+
+/*
+ * -----------------------------------------------------------------------------
+ * Extension functions
+ * -----------------------------------------------------------------------------
+ */
+
+int
+sa_stream_set_volume_abs(sa_stream_t *s, float vol) 
+{
+  unsigned int newVolume = 0;
+  int err;
+  audio_info_t audio_info;
+
+
+  newVolume = (AUDIO_MAX_GAIN-AUDIO_MIN_GAIN)*volAUDIO_MIN_GAIN;
+
+  /* Check if the new volume is valid or not */
+  if ( newVolume < AUDIO_MIN_GAIN || newVolume > AUDIO_MAX_GAIN )
+    return SA_ERROR_INVALID;
+
+  AUDIO_INITINFO(&audio_info);
+  audio_info.play.gain = newVolume;
+  err=ioctl(s->audio_fd,AUDIO_SETINFO,&audio_info);    // The actual setting of the parameters
+  if (err == -1)
+  {
+    perror("sa_stream_set_volume_abs failed") ; 
+    return SA_ERROR_SYSTEM;
+  }
+
+  return SA_SUCCESS;
+}
+
+int
+sa_stream_get_volume_abs(sa_stream_t *s, float *vol) 
+{
+  float volume;
+  int err;
+  audio_info_t audio_info;
+
+  if (s == NULL || s->audio_fd == NULL) {
+    return SA_ERROR_NO_INIT;
+  }
+
+  AUDIO_INITINFO(&audio_info);
+  err=ioctl(s->audio_fd,AUDIO_GETINFO,&audio_info);
+  if (err == -1)
+  {
+    perror("sa_stream_get_volume_abs failed");
+    return SA_ERROR_SYSTEM;
+  }
+
+  volume =  (float)((audio_info.play.gain - AUDIO_MIN_GAIN))/(AUDIO_MAX_GAIN - AUDIO_MIN_GAIN); 
+
+  *vol = volume;
+
+  return SA_SUCCESS;
+}
+
+/*
+ * -----------------------------------------------------------------------------
+ * Unsupported functions
+ * -----------------------------------------------------------------------------
+ */
+#define UNSUPPORTED(func)   func { return SA_ERROR_NOT_SUPPORTED; }
+
+UNSUPPORTED(int sa_stream_pause(sa_stream_t *s)) 
+UNSUPPORTED(int sa_stream_resume(sa_stream_t *s)) 
+UNSUPPORTED(int sa_stream_create_opaque(sa_stream_t **s, const char *client_name, sa_mode_t mode, const char *codec))
+UNSUPPORTED(int sa_stream_set_write_lower_watermark(sa_stream_t *s, size_t size))
+UNSUPPORTED(int sa_stream_set_read_lower_watermark(sa_stream_t *s, size_t size))
+UNSUPPORTED(int sa_stream_set_write_upper_watermark(sa_stream_t *s, size_t size))
+UNSUPPORTED(int sa_stream_set_read_upper_watermark(sa_stream_t *s, size_t size))
+UNSUPPORTED(int sa_stream_set_channel_map(sa_stream_t *s, const sa_channel_t map[], unsigned int n))
+UNSUPPORTED(int sa_stream_set_xrun_mode(sa_stream_t *s, sa_xrun_mode_t mode))
+UNSUPPORTED(int sa_stream_set_non_interleaved(sa_stream_t *s, int enable))
+UNSUPPORTED(int sa_stream_set_dynamic_rate(sa_stream_t *s, int enable))
+UNSUPPORTED(int sa_stream_set_driver(sa_stream_t *s, const char *driver))
+UNSUPPORTED(int sa_stream_start_thread(sa_stream_t *s, sa_event_callback_t callback))
+UNSUPPORTED(int sa_stream_stop_thread(sa_stream_t *s))
+UNSUPPORTED(int sa_stream_change_device(sa_stream_t *s, const char *device_name))
+UNSUPPORTED(int sa_stream_change_read_volume(sa_stream_t *s, const int32_t vol[], unsigned int n))
+UNSUPPORTED(int sa_stream_change_write_volume(sa_stream_t *s, const int32_t vol[], unsigned int n))
+UNSUPPORTED(int sa_stream_change_rate(sa_stream_t *s, unsigned int rate))
+UNSUPPORTED(int sa_stream_change_meta_data(sa_stream_t *s, const char *name, const void *data, size_t size))
+UNSUPPORTED(int sa_stream_change_user_data(sa_stream_t *s, const void *value))
+UNSUPPORTED(int sa_stream_set_adjust_rate(sa_stream_t *s, sa_adjust_t direction))
+UNSUPPORTED(int sa_stream_set_adjust_nchannels(sa_stream_t *s, sa_adjust_t direction))
+UNSUPPORTED(int sa_stream_set_adjust_pcm_format(sa_stream_t *s, sa_adjust_t direction))
+UNSUPPORTED(int sa_stream_set_adjust_watermarks(sa_stream_t *s, sa_adjust_t direction))
+UNSUPPORTED(int sa_stream_get_mode(sa_stream_t *s, sa_mode_t *access_mode))
+UNSUPPORTED(int sa_stream_get_codec(sa_stream_t *s, char *codec, size_t *size))
+UNSUPPORTED(int sa_stream_get_pcm_format(sa_stream_t *s, sa_pcm_format_t *format))
+UNSUPPORTED(int sa_stream_get_rate(sa_stream_t *s, unsigned int *rate))
+UNSUPPORTED(int sa_stream_get_nchannels(sa_stream_t *s, int *nchannels))
+UNSUPPORTED(int sa_stream_get_user_data(sa_stream_t *s, void **value))
+UNSUPPORTED(int sa_stream_get_write_lower_watermark(sa_stream_t *s, size_t *size))
+UNSUPPORTED(int sa_stream_get_read_lower_watermark(sa_stream_t *s, size_t *size))
+UNSUPPORTED(int sa_stream_get_write_upper_watermark(sa_stream_t *s, size_t *size))
+UNSUPPORTED(int sa_stream_get_read_upper_watermark(sa_stream_t *s, size_t *size))
+UNSUPPORTED(int sa_stream_get_channel_map(sa_stream_t *s, sa_channel_t map[], unsigned int *n))
+UNSUPPORTED(int sa_stream_get_xrun_mode(sa_stream_t *s, sa_xrun_mode_t *mode))
+UNSUPPORTED(int sa_stream_get_non_interleaved(sa_stream_t *s, int *enabled))
+UNSUPPORTED(int sa_stream_get_dynamic_rate(sa_stream_t *s, int *enabled))
+UNSUPPORTED(int sa_stream_get_driver(sa_stream_t *s, char *driver_name, size_t *size))
+UNSUPPORTED(int sa_stream_get_device(sa_stream_t *s, char *device_name, size_t *size))
+UNSUPPORTED(int sa_stream_get_read_volume(sa_stream_t *s, int32_t vol[], unsigned int *n))
+UNSUPPORTED(int sa_stream_get_write_volume(sa_stream_t *s, int32_t vol[], unsigned int *n))
+UNSUPPORTED(int sa_stream_get_meta_data(sa_stream_t *s, const char *name, void*data, size_t *size))
+UNSUPPORTED(int sa_stream_get_adjust_rate(sa_stream_t *s, sa_adjust_t *direction))
+UNSUPPORTED(int sa_stream_get_adjust_nchannels(sa_stream_t *s, sa_adjust_t *direction))
+UNSUPPORTED(int sa_stream_get_adjust_pcm_format(sa_stream_t *s, sa_adjust_t *direction))
+UNSUPPORTED(int sa_stream_get_adjust_watermarks(sa_stream_t *s, sa_adjust_t *direction))
+UNSUPPORTED(int sa_stream_get_state(sa_stream_t *s, sa_state_t *state))
+UNSUPPORTED(int sa_stream_get_event_error(sa_stream_t *s, sa_error_t *error))
+UNSUPPORTED(int sa_stream_get_event_notify(sa_stream_t *s, sa_notify_t *notify))
+UNSUPPORTED(int sa_stream_read(sa_stream_t *s, void *data, size_t nbytes))
+UNSUPPORTED(int sa_stream_read_ni(sa_stream_t *s, unsigned int channel, void *data, size_t nbytes))
+UNSUPPORTED(int sa_stream_write_ni(sa_stream_t *s, unsigned int channel, const void *data, size_t nbytes))
+UNSUPPORTED(int sa_stream_pwrite(sa_stream_t *s, const void *data, size_t nbytes, int64_t offset, sa_seek_t whence))
+UNSUPPORTED(int sa_stream_pwrite_ni(sa_stream_t *s, unsigned int channel, const void *data, size_t nbytes, int64_t offset, sa_seek_t whence))
+UNSUPPORTED(int sa_stream_get_read_size(sa_stream_t *s, size_t *size))
+UNSUPPORTED(int sa_stream_drain(sa_stream_t *s))
+
+const char *sa_strerror(int code) { return NULL; }
+
new file mode 100644
--- /dev/null
+++ b/media/libsydneyaudio/src/sydney_audio_waveapi.c
@@ -0,0 +1,711 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Initial Developer of the Original Code is
+ * CSIRO
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s): Marcin Lubonski 
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** *
+ */
+
+#include "sydney_audio.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <windows.h>
+#include <mmreg.h>
+#include <mmsystem.h>
+#include <math.h>
+
+
+// FIX ME: block size and block should be determined based on the OggPlay offset 
+// for audio track
+#define BLOCK_SIZE  2560
+#define BLOCK_COUNT 32
+#define DEFAULT_DEVICE_NAME "Default WAVE Device"
+#define DEFAULT_DEVICE WAVE_MAPPER
+
+#define VERBOSE_OUTPUT 1
+
+// INFO: if you get weird compile errors make sure there is no extra chars pass '\' 
+#if defined(VERBOSE_OUTPUT)
+#define WAVE_ERROR_VERBOSE(error, message) \
+  switch (error) { \
+    case MMSYSERR_ALLOCATED: \
+      printf("[WAVE API] Device allocation error returned while executing %s\n", message); \
+      break; \
+    case MMSYSERR_BADDEVICEID: \
+      printf("[WAVE API] Wrong device ID error returned while executing %s\n", message); \
+      break; \
+    case MMSYSERR_NODRIVER: \
+      printf("[WAVE API] System driver not present error returned while executing %s\n", message); \
+      break; \
+    case MMSYSERR_INVALHANDLE: \
+      printf("[WAVE API] Invalid device handle error returned while executing %s\n", message); \
+      break; \
+    case MMSYSERR_NOMEM: \
+      printf("[WAVE API] No memory error returned while executing %s\n", message); \
+      break; \
+    case MMSYSERR_NOTSUPPORTED: \
+      printf("[WAVE API] Not supported error returned while executing %s\n", message); \
+      break; \
+    case WAVERR_BADFORMAT: \
+      printf("[WAVE API] Not valid audio format returned while executing %s\n", message); \
+      break; \
+    case WAVERR_SYNC: \
+      printf("[WAVE API] Device synchronous error returned while executing %s\n", message); \
+      break; \
+    default: \
+      printf("[WAVE API] Error while executing %s\n", message); \
+      break; \
+  }
+#else
+#define WAVE_ERROR_VERBOSE(error, message) \
+  do {} while(0)
+#endif
+
+#define HANDLE_WAVE_ERROR(status, location) \
+  if (status != MMSYSERR_NOERROR) { \
+      WAVE_ERROR_VERBOSE(status, location); \
+      return getSAErrorCode(status); \
+  }
+
+#define ERROR_IF_NO_INIT(handle) \
+  if (handle == NULL) { \
+		return SA_ERROR_NO_INIT; \
+	}
+
+/* local implementation of the sa_stream_t type */
+struct sa_stream {   
+  char*           deviceName;
+  UINT				    device;
+  UINT				    channels;
+  UINT				    rate;
+	
+  sa_mode_t			  rwMode;
+  sa_pcm_format_t	format;   
+ 
+  HWAVEOUT			  hWaveOut;
+  HANDLE			    callbackEvent;
+  CRITICAL_SECTION  waveCriticalSection;  
+  WAVEHDR*			  waveBlocks;  
+  volatile int		waveFreeBlockCount;
+  int				      waveCurrentBlock;
+};
+
+
+/** Forward definitions of audio api specific functions */
+int allocateBlocks(int size, int count, WAVEHDR** blocks);
+int freeBlocks(WAVEHDR* blocks);
+int openAudio(sa_stream_t *s);
+int closeAudio(sa_stream_t * s);
+int writeAudio(sa_stream_t *s, LPSTR data, int bytes);
+int getSAErrorCode(int waveErrorCode);
+
+void CALLBACK waveOutProc(HWAVEOUT hWaveOut, UINT uMsg, 
+    DWORD dwInstance, DWORD dwParam1, DWORD dwParam2);
+
+/** Normal way to open a PCM device */
+int sa_stream_create_pcm(sa_stream_t **s, 
+                         const char *client_name, 
+                         sa_mode_t mode, 
+                         sa_pcm_format_t format, 
+                         unsigned int rate, 
+                         unsigned int nchannels) {
+  sa_stream_t * _s = NULL;
+  
+  ERROR_IF_NO_INIT(s);
+  
+  *s = NULL;
+  
+  /* FIX ME: for formats different than PCM extend using WAVEFORMATEXTENSIBLE */
+  if (format != SA_PCM_FORMAT_S16_NE) {
+    return SA_ERROR_NOT_SUPPORTED;
+  }
+
+  if (mode != SA_MODE_WRONLY) {
+    return SA_ERROR_NOT_SUPPORTED;
+  }
+
+  if ((_s = (sa_stream_t*)malloc(sizeof(sa_stream_t))) == NULL) {
+    return SA_ERROR_OOM;
+  }
+   
+  _s->rwMode = mode;
+  _s->format = format;
+  _s->rate = rate;
+  _s->channels = nchannels;
+  _s->deviceName = DEFAULT_DEVICE_NAME;
+  _s->device = DEFAULT_DEVICE;
+
+  *s = _s; 
+  return SA_SUCCESS;
+}
+
+/** Initialise the device */
+int sa_stream_open(sa_stream_t *s) {  
+  int status = SA_SUCCESS;
+
+  ERROR_IF_NO_INIT(s);
+
+  switch (s->rwMode) {
+    case SA_MODE_WRONLY: 
+      status = openAudio(s);
+      break;
+	default:
+      status = SA_ERROR_NOT_SUPPORTED;      
+      break;
+  }    
+  return status;
+}
+
+/** Interleaved playback function */
+int sa_stream_write(sa_stream_t *s, const void *data, size_t nbytes) {
+  int status = SA_SUCCESS;
+
+  ERROR_IF_NO_INIT(s);
+
+  status = writeAudio(s, (LPSTR)data, nbytes);
+
+  return status;
+}
+
+/** Query how much can be written without blocking */
+int sa_stream_get_write_size(sa_stream_t *s, size_t *size) {
+  unsigned int avail;
+  WAVEHDR* current;
+
+  ERROR_IF_NO_INIT(s);
+
+  EnterCriticalSection(&(s->waveCriticalSection));
+  avail = s->waveFreeBlockCount * BLOCK_SIZE;
+  if (s->waveFreeBlockCount != BLOCK_COUNT) {
+    current = &(s->waveBlocks[s->waveCurrentBlock]);
+    avail += BLOCK_SIZE - current->dwUser;
+  }
+  LeaveCriticalSection(&(s->waveCriticalSection));
+
+  *size = avail;
+
+  return SA_SUCCESS;
+}
+
+/** Close/destroy everything */
+int sa_stream_destroy(sa_stream_t *s) {
+  int status;
+
+  ERROR_IF_NO_INIT(s);
+  /* close and release all allocated resources */
+  status = closeAudio(s);
+
+  return status;
+}
+
+#define LEFT_CHANNEL_MASK 0x0000FFFF
+#define RIGHT_CHANNEL_MASK 0xFFFF0000
+
+/** 
+ * retrieved volume as an int in a scale from 0x0000 to 0xFFFF
+ * only one value for all channels
+ */
+int sa_stream_get_write_volume(sa_stream_t *s, int32_t vol[], unsigned int *n) {
+  int status;
+	DWORD volume;
+	WORD left;
+	WORD right;
+
+	ERROR_IF_NO_INIT(s);
+  
+	status = waveOutGetVolume(s->hWaveOut, &volume);
+	HANDLE_WAVE_ERROR(status, "reading audio volume level");
+
+	left = volume & LEFT_CHANNEL_MASK;
+	right = (volume & RIGHT_CHANNEL_MASK) >> 16;
+  vol[0] = (int32_t)(left + right /2);	
+
+	return SA_SUCCESS;
+
+}
+
+/** changes volume as an int in a scale from 0x0000 to 0xFFFF*/
+int sa_stream_change_write_volume(sa_stream_t *s, const int32_t vol[], unsigned int n) {
+  int status;
+	DWORD volume;
+	WORD left;
+	WORD right;
+	
+	ERROR_IF_NO_INIT(s);
+	
+  volume = (DWORD)vol[0];
+	left = volume & LEFT_CHANNEL_MASK;	  
+	right = left;	  
+	volume =  (left << 16) | right;	
+	
+	status = waveOutSetVolume(s->hWaveOut, volume);
+	HANDLE_WAVE_ERROR(status, "setting new audio volume level");	
+
+	return SA_SUCCESS;
+
+
+}
+
+/** sync/timing */
+int sa_stream_get_position(sa_stream_t *s, sa_position_t position, int64_t *pos) {
+	int status;
+  MMTIME  mm;
+
+  ERROR_IF_NO_INIT(s);
+
+  if (position != SA_POSITION_WRITE_HARDWARE) {
+    return SA_ERROR_NOT_SUPPORTED;
+  }
+  // request playback progress in bytes
+  mm.wType = TIME_BYTES;		
+	status = waveOutGetPosition(s->hWaveOut, &mm, sizeof(MMTIME));
+  HANDLE_WAVE_ERROR(status, "reading audio buffer position");
+  *pos = (int64_t)mm.u.cb;
+
+	return SA_SUCCESS;
+}
+
+/* Control/xrun */
+/** Resume playing after a pause */
+int sa_stream_resume(sa_stream_t *s) {
+  int status;  
+  
+  ERROR_IF_NO_INIT(s);
+
+  status = waveOutRestart(s->hWaveOut);
+  HANDLE_WAVE_ERROR(status, "resuming audio playback");
+
+  return SA_SUCCESS;
+}
+/** Pause audio playback (do not empty the buffer) */
+int sa_stream_pause(sa_stream_t *s) {
+  int status;
+
+  ERROR_IF_NO_INIT(s);
+  
+  status = waveOutPause(s->hWaveOut);
+  HANDLE_WAVE_ERROR(status, "resuming audio playback");
+
+  return SA_SUCCESS;
+}
+/** Block until all audio has been played */
+int sa_stream_drain(sa_stream_t *s) {
+  ERROR_IF_NO_INIT(s);
+  
+  /* wait for all blocks to complete */
+  EnterCriticalSection(&(s->waveCriticalSection));
+  while(s->waveFreeBlockCount < BLOCK_COUNT) {
+    LeaveCriticalSection(&(s->waveCriticalSection));
+    Sleep(10);
+    EnterCriticalSection(&(s->waveCriticalSection));
+  }
+  LeaveCriticalSection(&(s->waveCriticalSection));
+
+  return SA_SUCCESS;
+}
+
+/*
+ * -----------------------------------------------------------------------------
+ * Private WAVE API specific functions
+ * -----------------------------------------------------------------------------
+ */
+
+/** 
+ * \brief - allocate buffer for writing to system WAVE audio device
+ * \param size - size of each audio block
+ * \param cound - number of blocks to be allocated
+ * \param blocks - pointer to the blocks buffer to be allocated
+ * \return - completion status
+ */
+int allocateBlocks(int size, int count, WAVEHDR** blocks)
+{
+  unsigned char* buffer;    
+  int i;    
+  WAVEHDR* headers;
+  DWORD totalBufferSize = (size + sizeof(WAVEHDR)) * count;
+    
+  /* allocate memory on heap for the entire set in one go  */    
+  if((buffer = HeapAlloc(
+     GetProcessHeap(), 
+     HEAP_ZERO_MEMORY, 
+     totalBufferSize
+     )) == NULL) {
+      printf("Memory allocation error\n");
+      return SA_ERROR_OOM;
+    }
+
+  /* and set up the pointers to each bit */
+  headers = *blocks = (WAVEHDR*)buffer;
+  buffer += sizeof(WAVEHDR) * count;
+  for(i = 0; i < count; i++) {    
+	  headers[i].dwBufferLength = size;
+    headers[i].lpData = buffer;
+    buffer += size;
+  }
+    
+  return SA_SUCCESS;
+}
+
+/**
+ * \brief - free allocated audio buffer
+ * \param blocks - pointer to allocated the buffer of audio bloks
+ * \return - completion status
+ */
+int freeBlocks(WAVEHDR* blocks)
+{    
+  if (blocks == NULL) 
+    return SA_ERROR_INVALID;
+
+  /* and this is why allocateBlocks works the way it does */     
+  HeapFree(GetProcessHeap(), 0, blocks);
+  blocks = NULL;
+
+  return SA_SUCCESS;
+}
+
+/** 
+ * \brief - open system default WAVE device
+ * \param s - sydney audio stream handle
+ * \return - completion status
+ */ 
+int openAudio(sa_stream_t *s) {
+  int status;
+  WAVEFORMATEX wfx;    
+  UINT supported = FALSE;
+		  
+  status = allocateBlocks(BLOCK_SIZE, BLOCK_COUNT, &(s->waveBlocks));  
+	HANDLE_WAVE_ERROR(status, "allocating audio buffer blocks");
+  
+  s->waveFreeBlockCount	= BLOCK_COUNT;
+  s->waveCurrentBlock	= 0;  
+  wfx.nSamplesPerSec	= (DWORD)s->rate;	/* sample rate */
+  wfx.wBitsPerSample	= 16;				/* sample size */
+  wfx.nChannels			= s->channels;	/* channels    */
+  wfx.cbSize			= 0;				/* size of _extra_ info */
+  wfx.wFormatTag		= WAVE_FORMAT_PCM;
+  wfx.nBlockAlign		= (wfx.wBitsPerSample * wfx.nChannels) >> 3;
+  wfx.nAvgBytesPerSec	= wfx.nBlockAlign * wfx.nSamplesPerSec;
+
+  supported = waveOutOpen(NULL, WAVE_MAPPER, &wfx, (DWORD_PTR)0, (DWORD_PTR)0, 
+				WAVE_FORMAT_QUERY);
+  if (supported == MMSYSERR_NOERROR) { // audio device opened sucessfully 
+    status = waveOutOpen((LPHWAVEOUT)&(s->hWaveOut), WAVE_MAPPER, &wfx, 
+	  (DWORD_PTR)waveOutProc, (DWORD_PTR)s, CALLBACK_FUNCTION);
+    HANDLE_WAVE_ERROR(status, "opening audio device for playback");
+		printf("Audio device sucessfully opened\n");
+  } 
+  else if (supported == WAVERR_BADFORMAT) {
+    printf("Requested format not supported...\n");
+	  // clean up the memory
+	  freeBlocks(s->waveBlocks);
+    return SA_ERROR_NOT_SUPPORTED;
+  } 
+  else {
+    printf("Error opening default audio device. Exiting...\n");
+	  // clean up the memory
+	  freeBlocks(s->waveBlocks);
+    return SA_ERROR_SYSTEM;
+  }
+  // create notification for data written to a device
+  s->callbackEvent = CreateEvent(0, FALSE, FALSE, 0);
+  // initialise critical section for operations on waveFreeBlockCound variable
+  InitializeCriticalSection(&(s->waveCriticalSection));
+
+  return SA_SUCCESS;
+}
+/**
+ * \brief - closes opened audio device handle
+ * \param s - sydney audio stream handle
+ * \return - completion status
+ */
+int closeAudio(sa_stream_t * s) {
+  int status, i;
+  
+  // reseting audio device and flushing buffers
+  status = waveOutReset(s->hWaveOut);    
+  HANDLE_WAVE_ERROR(status, "resetting audio device");
+  
+  /* wait for all blocks to complete */  
+  while(s->waveFreeBlockCount < BLOCK_COUNT)
+	  Sleep(10);
+
+  /* unprepare any blocks that are still prepared */  
+  for(i = 0; i < s->waveFreeBlockCount; i++) {
+    if(s->waveBlocks[i].dwFlags & WHDR_PREPARED) {
+	    status = waveOutUnprepareHeader(s->hWaveOut, &(s->waveBlocks[i]), sizeof(WAVEHDR));
+      HANDLE_WAVE_ERROR(status, "closing audio device");
+    }
+  }    
+
+  freeBlocks(s->waveBlocks);  
+  status = waveOutClose(s->hWaveOut);    
+  HANDLE_WAVE_ERROR(status, "closing audio device");
+
+  DeleteCriticalSection(&(s->waveCriticalSection));
+  CloseHandle(s->callbackEvent);
+  printf("[audio] audio resources cleanup completed\n");
+  
+  return SA_SUCCESS;
+}
+/**
+ * \brief - writes PCM audio samples to audio device
+ * \param s - valid handle to opened sydney stream
+ * \param data - pointer to memory storing audio samples to be played
+ * \param nsamples - number of samples in the memory pointed by previous parameter
+ * \return - completion status
+ */
+int writeAudio(sa_stream_t *s, LPSTR data, int bytes) {    
+  UINT status;
+  WAVEHDR* current;	  
+  int remain;
+
+  current = &(s->waveBlocks[s->waveCurrentBlock]);
+  
+  while(bytes > 0) {
+    /* first make sure the header we're going to use is unprepared */
+    if(current->dwFlags & WHDR_PREPARED) {      
+        status = waveOutUnprepareHeader(s->hWaveOut, current, sizeof(WAVEHDR));         
+        HANDLE_WAVE_ERROR(status, "preparing audio headers for writing");
+    }
+		  
+    if(bytes < (int)(BLOCK_SIZE - current->dwUser)) {							  	    
+		  memcpy(current->lpData + current->dwUser, data, bytes);
+      current->dwUser += bytes;
+      break;
+    }
+	
+    /* remain is even as BLOCK_SIZE and dwUser are even too */
+    remain = BLOCK_SIZE - current->dwUser;      
+  	memcpy(current->lpData + current->dwUser, data, remain);
+    bytes -= remain;
+    data += remain;
+	  current->dwBufferLength = BLOCK_SIZE;
+	  /* write to audio device */
+    waveOutPrepareHeader(s->hWaveOut, current, sizeof(WAVEHDR));
+	  status = waveOutWrite(s->hWaveOut, current, sizeof(WAVEHDR));      
+    HANDLE_WAVE_ERROR(status, "writing audio to audio device");
+      
+    EnterCriticalSection(&(s->waveCriticalSection));
+    s->waveFreeBlockCount--;
+    LeaveCriticalSection(&(s->waveCriticalSection));
+    /*
+     * wait for a block to become free
+     */
+    while (!(s->waveFreeBlockCount)) {
+        //printf("All audio buffer blocks empty\n");        
+      WaitForSingleObject(s->callbackEvent, INFINITE);
+        //Sleep(10);
+    }		  
+		
+    /*
+     * point to the next block
+     */
+    (s->waveCurrentBlock)++;
+    (s->waveCurrentBlock) %= BLOCK_COUNT;		
+
+    current = &(s->waveBlocks[s->waveCurrentBlock]);
+    current->dwUser = 0;
+  }
+  return SA_SUCCESS;
+}
+
+/**
+ * \brief - audio callback function called when next WAVE header is played by audio device
+ */
+void CALLBACK waveOutProc(
+    HWAVEOUT hWaveOut, 
+    UINT uMsg, 
+    DWORD dwInstance,  
+    DWORD dwParam1,    
+    DWORD dwParam2     
+)
+{
+    /*
+     * pointer to free block counter
+     */
+    sa_stream_t* handle = (sa_stream_t*)dwInstance;
+    /*
+     * ignore calls that occur due to openining and closing the
+     * device.
+     */
+    if(uMsg != WOM_DONE)
+        return;
+
+    EnterCriticalSection(&(handle->waveCriticalSection));
+    (handle->waveFreeBlockCount)++;
+    if ((handle->waveFreeBlockCount) == 1) 
+       SetEvent(handle->callbackEvent);
+    LeaveCriticalSection(&(handle->waveCriticalSection));	
+}
+
+/**
+ * \brief - converts frequently reported WAVE error codes to Sydney audio API codes
+ */
+int getSAErrorCode(int waveErrorCode) {
+  int error = SA_ERROR_NOT_SUPPORTED;
+
+  switch (waveErrorCode) {
+    case MMSYSERR_NOERROR: 
+      error = SA_SUCCESS;
+      break;
+    case MMSYSERR_ALLOCATED: 
+      error = SA_ERROR_SYSTEM;
+      break;
+    case MMSYSERR_BADDEVICEID:
+      error = SA_ERROR_INVALID;
+      break;
+    case MMSYSERR_NODRIVER:
+      error = SA_ERROR_NO_DRIVER;
+      break;
+    case MMSYSERR_NOTSUPPORTED:
+      error = SA_ERROR_NOT_SUPPORTED;
+      break;          
+    case MMSYSERR_NOMEM: 
+      error = SA_ERROR_OOM;
+      break;
+    case MMSYSERR_INVALHANDLE:
+      error = SA_ERROR_INVALID;
+      break;
+    case WAVERR_BADFORMAT: 
+      error = SA_ERROR_NOT_SUPPORTED;
+      break;
+    case WAVERR_SYNC: 
+      error = SA_ERROR_NOT_SUPPORTED;
+      break;    
+  }
+  return error;
+}
+
+
+/*
+ * -----------------------------------------------------------------------------
+ * Functions to be implemented next 
+ * -----------------------------------------------------------------------------
+ */
+
+#define NOT_IMPLEMENTED(func)   func { return SA_ERROR_NOT_SUPPORTED; }
+
+/* "Soft" params */
+NOT_IMPLEMENTED(int sa_stream_set_write_lower_watermark(sa_stream_t *s, size_t size))
+NOT_IMPLEMENTED(int sa_stream_set_read_lower_watermark(sa_stream_t *s, size_t size))
+NOT_IMPLEMENTED(int sa_stream_set_write_upper_watermark(sa_stream_t *s, size_t size))
+NOT_IMPLEMENTED(int sa_stream_set_read_upper_watermark(sa_stream_t *s, size_t size))
+
+/** Set the mapping between channels and the loudspeakers */
+NOT_IMPLEMENTED(int sa_stream_set_channel_map(sa_stream_t *s, const sa_channel_t map[], unsigned int n))
+
+/* Query functions */
+NOT_IMPLEMENTED(int sa_stream_get_mode(sa_stream_t *s, sa_mode_t *access_mode))
+NOT_IMPLEMENTED(int sa_stream_get_pcm_format(sa_stream_t *s, sa_pcm_format_t *format))
+NOT_IMPLEMENTED(int sa_stream_get_rate(sa_stream_t *s, unsigned int *rate))
+NOT_IMPLEMENTED(int sa_stream_get_nchannels(sa_stream_t *s, int *nchannels))
+NOT_IMPLEMENTED(int sa_stream_get_device(sa_stream_t *s, char *device_name, size_t *size))
+NOT_IMPLEMENTED(int sa_stream_get_write_lower_watermark(sa_stream_t *s, size_t *size))
+NOT_IMPLEMENTED(int sa_stream_get_read_lower_watermark(sa_stream_t *s, size_t *size))
+NOT_IMPLEMENTED(int sa_stream_get_write_upper_watermark(sa_stream_t *s, size_t *size))
+NOT_IMPLEMENTED(int sa_stream_get_read_upper_watermark(sa_stream_t *s, size_t *size))
+NOT_IMPLEMENTED(int sa_stream_get_channel_map(sa_stream_t *s, sa_channel_t map[], unsigned int *n))
+
+/*
+ * -----------------------------------------------------------------------------
+ * Unsupported functions
+ * -----------------------------------------------------------------------------
+ */
+#define UNSUPPORTED(func)   func { return SA_ERROR_NOT_SUPPORTED; }
+
+/** Create an opaque (e.g. AC3) codec stream */
+UNSUPPORTED(int sa_stream_create_opaque(sa_stream_t **s, const char *client_name, sa_mode_t mode, const char *codec))
+/** Whether xruns cause the card to reset */
+UNSUPPORTED(int sa_stream_set_xrun_mode(sa_stream_t *s, sa_xrun_mode_t mode))
+/** Set the device to non-interleaved mode */
+UNSUPPORTED(int sa_stream_set_non_interleaved(sa_stream_t *s, int enable))
+/** Require dynamic sample rate */
+UNSUPPORTED(int sa_stream_set_dynamic_rate(sa_stream_t *s, int enable))
+/** Select driver */
+UNSUPPORTED(int sa_stream_set_driver(sa_stream_t *s, const char *driver))
+/** Start callback */
+UNSUPPORTED(int sa_stream_start_thread(sa_stream_t *s, sa_event_callback_t callback))
+/** Stop callback */
+UNSUPPORTED(int sa_stream_stop_thread(sa_stream_t *s))
+/** Change the device connected to the stream */
+UNSUPPORTED(int sa_stream_change_device(sa_stream_t *s, const char *device_name))
+/** volume in hundreths of dB*/
+UNSUPPORTED(int sa_stream_change_read_volume(sa_stream_t *s, const int32_t vol[], unsigned int n))
+/** Change the sampling rate */
+UNSUPPORTED(int sa_stream_change_rate(sa_stream_t *s, unsigned int rate))
+/** Change some meta data that is attached to the stream */
+UNSUPPORTED(int sa_stream_change_meta_data(sa_stream_t *s, const char *name, const void *data, size_t size))
+/** Associate opaque user data */
+UNSUPPORTED(int sa_stream_change_user_data(sa_stream_t *s, const void *value))
+/* Hardware-related. This is implementation-specific and hardware specific. */
+UNSUPPORTED(int sa_stream_set_adjust_rate(sa_stream_t *s, sa_adjust_t direction))
+UNSUPPORTED(int sa_stream_set_adjust_nchannels(sa_stream_t *s, sa_adjust_t direction))
+UNSUPPORTED(int sa_stream_set_adjust_pcm_format(sa_stream_t *s, sa_adjust_t direction))
+UNSUPPORTED(int sa_stream_set_adjust_watermarks(sa_stream_t *s, sa_adjust_t direction))
+/* Query functions */
+UNSUPPORTED(int sa_stream_get_codec(sa_stream_t *s, char *codec, size_t *size))
+UNSUPPORTED(int sa_stream_get_user_data(sa_stream_t *s, void **value))
+
+UNSUPPORTED(int sa_stream_get_xrun_mode(sa_stream_t *s, sa_xrun_mode_t *mode))
+UNSUPPORTED(int sa_stream_get_non_interleaved(sa_stream_t *s, int *enabled))
+UNSUPPORTED(int sa_stream_get_dynamic_rate(sa_stream_t *s, int *enabled))
+UNSUPPORTED(int sa_stream_get_driver(sa_stream_t *s, char *driver_name, size_t *size))            
+UNSUPPORTED(int sa_stream_get_read_volume(sa_stream_t *s, int32_t vol[], unsigned int *n))
+UNSUPPORTED(int sa_stream_get_meta_data(sa_stream_t *s, const char *name, void*data, size_t *size))
+UNSUPPORTED(int sa_stream_get_adjust_rate(sa_stream_t *s, sa_adjust_t *direction))
+UNSUPPORTED(int sa_stream_get_adjust_nchannels(sa_stream_t *s, sa_adjust_t *direction))
+UNSUPPORTED(int sa_stream_get_adjust_pcm_format(sa_stream_t *s, sa_adjust_t *direction))
+UNSUPPORTED(int sa_stream_get_adjust_watermarks(sa_stream_t *s, sa_adjust_t *direction))
+/** Get current state of the audio device */
+UNSUPPORTED(int sa_stream_get_state(sa_stream_t *s, sa_state_t *state))
+/** Obtain the error code */
+UNSUPPORTED(int sa_stream_get_event_error(sa_stream_t *s, sa_error_t *error))
+/** Obtain the notification code */
+UNSUPPORTED(int sa_stream_get_event_notify(sa_stream_t *s, sa_notify_t *notify))
+
+/* Blocking IO calls */
+/** Interleaved capture function */
+UNSUPPORTED(int sa_stream_read(sa_stream_t *s, void *data, size_t nbytes))
+/** Non-interleaved capture function */
+UNSUPPORTED(int sa_stream_read_ni(sa_stream_t *s, unsigned int channel, void *data, size_t nbytes))
+
+/** Non-interleaved playback function */
+UNSUPPORTED(int sa_stream_write_ni(sa_stream_t *s, unsigned int channel, const void *data, size_t nbytes))
+/** Interleaved playback function with seek offset */
+UNSUPPORTED(int sa_stream_pwrite(sa_stream_t *s, const void *data, size_t nbytes, int64_t offset, sa_seek_t whence))
+/** Non-interleaved playback function with seek offset */
+UNSUPPORTED(int sa_stream_pwrite_ni(sa_stream_t *s, unsigned int channel, const void *data, size_t nbytes, int64_t offset, sa_seek_t whence))
+
+/** Query how much can be read without blocking */
+UNSUPPORTED(int sa_stream_get_read_size(sa_stream_t *s, size_t *size))
+
+/** Return a human readable error */
+const char *sa_strerror(int code);
new file mode 100644
--- /dev/null
+++ b/media/libsydneyaudio/update.sh
@@ -0,0 +1,7 @@
+# Usage: ./update.sh <oggplay_src_directory>
+#
+# Copies the needed files from a directory containing the original
+# liboggplay source that we need for the Mozilla HTML5 media support.
+cp $1/include/sydney_audio.h include/sydney_audio.h
+cp $1/src/*.c src/
+cp $1/AUTHORS ./AUTHORS
--- a/toolkit/toolkit-makefiles.sh
+++ b/toolkit/toolkit-makefiles.sh
@@ -329,18 +329,20 @@ MAKEFILES_libfishsound="
 MAKEFILES_liboggplay="
   media/liboggplay/Makefile
   media/liboggplay/src/Makefile
   media/liboggplay/src/liboggplay/Makefile
   media/liboggplay/include/Makefile
   media/liboggplay/include/oggplay/Makefile
 "
 
-MAKEFILES_liboggplay_audio="
-  media/liboggplay_audio/Makefile
+MAKEFILES_libsydneyaudio="
+  media/libsydneyaudio/Makefile
+  media/libsydneyaudio/include/Makefile
+  media/libsydneyaudio/src/Makefile
 "
 
 MAKEFILES_oji="
   modules/oji/Makefile
   modules/oji/public/Makefile
   modules/oji/src/Makefile
   plugin/oji/JEP/Makefile
 "
@@ -1121,11 +1123,11 @@ fi
 if [ "$MOZ_OGG" ]; then
  add_makefiles "
    $MAKEFILES_libvorbis
    $MAKEFILES_libtheora
    $MAKEFILES_liboggz
    $MAKEFILES_libogg
    $MAKEFILES_libfishsound
    $MAKEFILES_liboggplay
-   $MAKEFILES_liboggplay_audio
+   $MAKEFILES_libsydneyaudio
  "
 fi
--- a/toolkit/toolkit-tiers.mk
+++ b/toolkit/toolkit-tiers.mk
@@ -118,18 +118,18 @@ ifdef MOZ_JSDEBUGGER
 tier_gecko_dirs += js/jsd
 endif
 
 ifdef MOZ_OGG
 tier_gecko_dirs += \
 		media/libfishsound \
 		media/libogg \
 		media/liboggplay \
-		media/liboggplay_audio \
 		media/liboggz \
+		media/libsydneyaudio \
 		media/libtheora \
 		media/libvorbis \
 		$(NULL)
 endif
 
 tier_gecko_dirs	+= \
 		uriloader \
 		modules/libimg \