summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFilippo Giunchedi <filippo@esaurito.net>2009-11-06 13:42:56 (GMT)
committer Filippo Giunchedi <filippo@esaurito.net>2009-11-14 12:50:50 (GMT)
commit9f761a0edd9d0d02f75fe5b0e5e4162ef208bc84 (patch)
tree99474582121d88c144a9b6830a013ad01c0a35ad
parent022e4463f8d6876733524fd5a6cbdbd76cb0bb99 (diff)
remove shipped portaudio
-rw-r--r--AUTHORS1
-rw-r--r--configure.ac31
-rw-r--r--lib/portaudio/LICENSE65
-rw-r--r--lib/portaudio/Makefile.am18
-rw-r--r--lib/portaudio/README81
-rw-r--r--lib/portaudio/pa_convert.c470
-rw-r--r--lib/portaudio/pa_host.h189
-rw-r--r--lib/portaudio/pa_lib.c806
-rw-r--r--lib/portaudio/pa_mac.c1692
-rw-r--r--lib/portaudio/pa_mac_core.c2142
-rw-r--r--lib/portaudio/pa_trace.c83
-rw-r--r--lib/portaudio/pa_trace.h67
-rw-r--r--lib/portaudio/pa_unix.c1127
-rw-r--r--lib/portaudio/pa_unix.h142
-rw-r--r--lib/portaudio/pa_unix_oss.c395
-rw-r--r--lib/portaudio/pa_unix_solaris.c402
-rw-r--r--lib/portaudio/portaudio.h465
-rw-r--r--lib/portaudio/ringbuffer.c199
-rw-r--r--lib/portaudio/ringbuffer.h102
-rw-r--r--src/dev_sound.h2
20 files changed, 2 insertions, 8477 deletions
diff --git a/AUTHORS b/AUTHORS
index 9e46839..46910b2 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -51,7 +51,6 @@ MuSE redistributes, linked statically, the following libraries:
= libshout by Jack Moffit, Chad Armstrong, Scott Manley and OddSock
= libcdk by Mike Glover
= the secret rabbit code (libresample) by Eric de Castro Lopo
- = portaudio by Ross Bencina and Phil Burk
MuSE can link itself dinamically to the following libraries:
= libogg, libvorbis, libvorbisfile - www.xiph.org
diff --git a/configure.ac b/configure.ac
index cf8de6f..a7b6697 100644
--- a/configure.ac
+++ b/configure.ac
@@ -27,9 +27,6 @@ AC_MSG_CHECKING(for which platform we are compiling)
case "$host_os" in
*linux*)
AC_MSG_RESULT([Linux])
- # HAVE_LINUX/UNIX are needed by portaudio only
- AC_DEFINE(HAVE_LINUX,1,[define if compiling for Linux])
- AC_DEFINE(HAVE_UNIX,1,[define if compiling for UNIX])
have_linux=yes
;;
@@ -44,7 +41,6 @@ case "$host_os" in
*bsd*)
AC_MSG_RESULT(${host})
AC_DEFINE(HAVE_BSD,1,[define if compiling for BSD])
- AC_DEFINE(HAVE_UNIX,1,[define if compiling for UNIX])
have_bsd=yes
;;
@@ -293,27 +289,8 @@ AC_SUBST(GUI_CFLAGS)
dnl ==============================================================
dnl Choose external portaudio library
dnl =========================================
-AC_MSG_CHECKING(if external portaudio library is requested)
-PORTAUDIO_LIBS="\$(top_builddir)/lib/portaudio/libportaudio.a"
-PORTAUDIO_CFLAGS="-I\$(top_srcdir)/lib/portaudio"
-PORTAUDIO_DIRS="portaudio"
-# add -lossaudio library needed for BSD systems
-if test x$have_bsd = xyes; then
- PORTAUDIO_LIBS="$PORTAUDIO_LIBS -lossaudio"
-fi
-AC_ARG_WITH(portaudio,
-[ --with-portaudio=/sw portaudio lib prefix],
-[if test -n "$withval" && test -d "$withval" ; then
- external_portaudio=yes
- PORTAUDIO_LIBS="$withval/lib/libportaudio.a -I$withval/pa_common "
- PORTAUDIO_CFLAGS="-I$withval/include -I$withval/pa_common "
- PORTAUDIO_DIRS=""
- AC_MSG_RESULT(yes)
- fi],[AC_MSG_RESULT(no)])
-AC_SUBST(PORTAUDIO_LIBS)
-AC_SUBST(PORTAUDIO_CFLAGS)
-AC_SUBST(PORTAUDIO_DIRS)
-
+PKG_CHECK_MODULES(PORTAUDIO, portaudio-2.0, [:],
+ AC_MSG_ERROR([*** portaudio 19 not found!]))
dnl ==============================================================
@@ -409,7 +386,6 @@ AC_CONFIG_FILES([
Makefile
lib/Makefile
lib/libmpeg/Makefile
-lib/portaudio/Makefile
src/ncursesgui/libcdk/Makefile
doc/muse.doxygen
])
@@ -460,9 +436,6 @@ fi
if test "${want_ncurses_gui}" = "yes"; then
echo ":: Building the NCURSES user interface"
fi
-if test "$external_portaudio" = "yes"; then
- echo ":: Embedding external portaudio from $PORTAUDIO_LIBS"
-fi
if test "$enable_profiling" = "yes"; then
echo ":: PROFILING informations ON (to use with gprof)"
diff --git a/lib/portaudio/LICENSE b/lib/portaudio/LICENSE
deleted file mode 100644
index 105da3f..0000000
--- a/lib/portaudio/LICENSE
+++ /dev/null
@@ -1,65 +0,0 @@
-Portable header file to contain:
-/*
- * PortAudio Portable Real-Time Audio Library
- * PortAudio API Header File
- * Latest version available at: http://www.audiomulch.com/portaudio/
- *
- * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files
- * (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * Any person wishing to distribute modifications to the Software is
- * requested to send the modifications to the original developer so that
- * they can be incorporated into the canonical version.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- */
-
-
-Implementation files to contain:
-/*
- * PortAudio Portable Real-Time Audio Library
- * Latest version at: http://www.audiomulch.com/portaudio/
- * <platform> Implementation
- * Copyright (c) 1999-2000 <author(s)>
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files
- * (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * Any person wishing to distribute modifications to the Software is
- * requested to send the modifications to the original developer so that
- * they can be incorporated into the canonical version.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- */ \ No newline at end of file
diff --git a/lib/portaudio/Makefile.am b/lib/portaudio/Makefile.am
deleted file mode 100644
index 5a60e80..0000000
--- a/lib/portaudio/Makefile.am
+++ /dev/null
@@ -1,18 +0,0 @@
-EXTRA_DIST = LICENSE
-
-AUTOMAKE_OPTIONS = foreign
-
-noinst_HEADERS = pa_host.h pa_trace.h pa_unix.h portaudio.h ringbuffer.h
-
-noinst_LIBRARIES = libportaudio.a
-
-libportaudio_a_SOURCES = \
- pa_convert.c \
- pa_lib.c \
- pa_trace.c \
- pa_unix.c \
- pa_unix_oss.c \
- pa_unix_solaris.c \
- pa_mac.c \
- pa_mac_core.c \
- ringbuffer.c
diff --git a/lib/portaudio/README b/lib/portaudio/README
deleted file mode 100644
index d1e5d7d..0000000
--- a/lib/portaudio/README
+++ /dev/null
@@ -1,81 +0,0 @@
-README for PortAudio
-Implementations for PC DirectSound and Mac SoundManager
-
-/*
- * PortAudio Portable Real-Time Audio Library
- * Latest Version at: http://www.portaudio.com//
- *
- * Copyright (c) 1999-2000 Phil Burk and Ross Bencina
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files
- * (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * Any person wishing to distribute modifications to the Software is
- * requested to send the modifications to the original developer so that
- * they can be incorporated into the canonical version.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- */
-
-PortAudio is a portable audio I/O library designed for cross-platform
-support of audio. It uses a callback mechanism to request audio processing.
-Audio can be generated in various formats, including 32 bit floating point,
-and will be converted to the native format internally.
-
-Documentation:
- See "pa_common/portaudio.h" for API spec.
- See docs folder for a tutorial.
- Also see http://www.portaudio.com/docs/
- And see "pa_tests/patest_saw.c" for an example.
-
-For information on compiling programs with PortAudio, please see the
-tutorial at:
-
- http://www.portaudio.com/docs/pa_tutorial.html
-
-Important Files and Folders:
- pa_common/ = platform independant code
- pa_common/portaudio.h = header file for PortAudio API. Specifies API.
- pa_common/pa_lib.c = host independant code for all implementations.
-
- pablio = simple blocking read/write interface
-
-Platform Implementations
- pa_asio = ASIO for Windows and Macintosh
- pa_beos = BeOS
- pa_mac = Macintosh Sound Manager for OS 8,9 and Carbon
- pa_mac_core = Macintosh Core Audio for OS X
- pa_sgi = Silicon Graphics AL
- pa_unix_oss = OSS implementation for various Unixes
- pa_win_ds = Windows Direct Sound
- pa_win_wmme = Windows MME (most widely supported)
-
-Test Programs
- pa_tests/pa_fuzz.c = guitar fuzz box
- pa_tests/pa_devs.c = print a list of available devices
- pa_tests/pa_minlat.c = determine minimum latency for your machine
- pa_tests/paqa_devs.c = self test that opens all devices
- pa_tests/paqa_errs.c = test error detection and reporting
- pa_tests/patest_clip.c = hear a sine wave clipped and unclipped
- pa_tests/patest_dither.c = hear effects of dithering (extremely subtle)
- pa_tests/patest_pink.c = fun with pink noise
- pa_tests/patest_record.c = record and playback some audio
- pa_tests/patest_maxsines.c = how many sine waves can we play? Tests Pa_GetCPULoad().
- pa_tests/patest_sine.c = output a sine wave in a simple PA app
- pa_tests/patest_sync.c = test syncronization of audio and video
- pa_tests/patest_wire.c = pass input to output, wire simulator
diff --git a/lib/portaudio/pa_convert.c b/lib/portaudio/pa_convert.c
deleted file mode 100644
index 692f6ee..0000000
--- a/lib/portaudio/pa_convert.c
+++ /dev/null
@@ -1,470 +0,0 @@
-/*
- * pa_conversions.c
- * portaudio
- *
- * Created by Phil Burk on Mon Mar 18 2002.
- *
- */
-#include <stdio.h>
-
-#include "portaudio.h"
-#include "pa_host.h"
-
-#define CLIP( val, min, max ) { val = ((val) < (min)) ? min : (((val) < (max)) ? (max) : (val)); }
-
-/*************************************************************************/
-static void PaConvert_Float32_Int16(
- float *sourceBuffer, int sourceStride,
- short *targetBuffer, int targetStride,
- int numSamples )
-{
- int i;
- for( i=0; i<numSamples; i++ )
- {
- short samp = (short) (*sourceBuffer * (32767.0f));
- *targetBuffer = samp;
- sourceBuffer += sourceStride;
- targetBuffer += targetStride;
- }
-}
-
-/*************************************************************************/
-static void PaConvert_Float32_Int16_Clip(
- float *sourceBuffer, int sourceStride,
- short *targetBuffer, int targetStride,
- int numSamples )
-{
- int i;
- for( i=0; i<numSamples; i++ )
- {
- int32_t samp = (long) (*sourceBuffer * (32767.0f));
- CLIP( samp, -0x8000, 0x7FFF );
- *targetBuffer = (short) samp;
- sourceBuffer += sourceStride;
- targetBuffer += targetStride;
- }
-}
-
-/*************************************************************************/
-static void PaConvert_Float32_Int16_ClipDither(
- float *sourceBuffer, int sourceStride,
- short *targetBuffer, int targetStride,
- int numSamples )
-{
- int i;
- for( i=0; i<numSamples; i++ )
- {
- // use smaller scaler to prevent overflow when we add the dither
- float dither = PaConvert_TriangularDither() * PA_DITHER_SCALE;
- float dithered = (*sourceBuffer * (32766.0f)) + dither;
- int32_t samp = (long) dithered;
- CLIP( samp, -0x8000, 0x7FFF );
- *targetBuffer = (short) samp;
- sourceBuffer += sourceStride;
- targetBuffer += targetStride;
- }
-}
-
-/*************************************************************************/
-static void PaConvert_Float32_Int16_Dither(
- float *sourceBuffer, int sourceStride,
- short *targetBuffer, int targetStride,
- int numSamples )
-{
- int i;
- for( i=0; i<numSamples; i++ )
- {
- // use smaller scaler to prevent overflow when we add the dither
- float dither = PaConvert_TriangularDither() * PA_DITHER_SCALE;
- float dithered = (*sourceBuffer * (32766.0f)) + dither;
- *targetBuffer = (short) dithered;
- sourceBuffer += sourceStride;
- targetBuffer += targetStride;
- }
-}
-
-
-/*************************************************************************/
-static void PaConvert_Int16_Float32(
- short *sourceBuffer, int sourceStride,
- float *targetBuffer, int targetStride,
- int numSamples )
-{
- int i;
- for( i=0; i<numSamples; i++ )
- {
- float samp = *sourceBuffer * (1.0f / 32768.0f);
- *targetBuffer = samp;
- sourceBuffer += sourceStride;
- targetBuffer += targetStride;
- }
-}
-
-/*************************************************************************/
-static void PaConvert_Float32_Int8(
- float *sourceBuffer, int sourceStride,
- char *targetBuffer, int targetStride,
- int numSamples )
-{
- int i;
- for( i=0; i<numSamples; i++ )
- {
- char samp = (char) (*sourceBuffer * (127.0));
- *targetBuffer = samp;
- sourceBuffer += sourceStride;
- targetBuffer += targetStride;
- }
-}
-
-
-/*************************************************************************/
-static void PaConvert_Float32_Int8_Clip(
- float *sourceBuffer, int sourceStride,
- char *targetBuffer, int targetStride,
- int numSamples )
-{
- int i;
- for( i=0; i<numSamples; i++ )
- {
- int32_t samp = (long) (*sourceBuffer * 127.0f);
- CLIP( samp, -0x80, 0x7F );
- *targetBuffer = (char) samp;
- sourceBuffer += sourceStride;
- targetBuffer += targetStride;
- }
-}
-
-/*************************************************************************/
-static void PaConvert_Float32_Int8_ClipDither(
- float *sourceBuffer, int sourceStride,
- char *targetBuffer, int targetStride,
- int numSamples )
-{
- int i;
- for( i=0; i<numSamples; i++ )
- {
- // use smaller scaler to prevent overflow when we add the dither
- float dither = PaConvert_TriangularDither() * PA_DITHER_SCALE;
- float dithered = (*sourceBuffer * (126.0f)) + dither;
- int32_t samp = (long) dithered;
- CLIP( samp, -0x80, 0x7F );
- *targetBuffer = (char) samp;
- sourceBuffer += sourceStride;
- targetBuffer += targetStride;
- }
-}
-
-/*************************************************************************/
-static void PaConvert_Float32_Int8_Dither(
- float *sourceBuffer, int sourceStride,
- char *targetBuffer, int targetStride,
- int numSamples )
-{
- int i;
- for( i=0; i<numSamples; i++ )
- {
- // use smaller scaler to prevent overflow when we add the dither
- float dither = PaConvert_TriangularDither() * PA_DITHER_SCALE; //FIXME
- float dithered = (*sourceBuffer * (126.0f)) + dither;
- int32_t samp = (long) dithered;
- *targetBuffer = (char) samp;
- sourceBuffer += sourceStride;
- targetBuffer += targetStride;
- }
-}
-
-/*************************************************************************/
-static void PaConvert_Int8_Float32(
- char *sourceBuffer, int sourceStride,
- float *targetBuffer, int targetStride,
- int numSamples )
-{
- int i;
- for( i=0; i<numSamples; i++ )
- {
- float samp = *sourceBuffer * (1.0f / 128.0f);
- *targetBuffer = samp;
- sourceBuffer += sourceStride;
- targetBuffer += targetStride;
- }
-}
-
-/*************************************************************************/
-static void PaConvert_Float32_UInt8(
- float *sourceBuffer, int sourceStride,
- unsigned char *targetBuffer, int targetStride,
- int numSamples )
-{
- int i;
- for( i=0; i<numSamples; i++ )
- {
- unsigned char samp = (unsigned char)(128 + (*sourceBuffer * (127.0)));
- *targetBuffer = samp;
- sourceBuffer += sourceStride;
- targetBuffer += targetStride;
- }
-}
-
-/*************************************************************************/
-static void PaConvert_UInt8_Float32(
- unsigned char *sourceBuffer, int sourceStride,
- float *targetBuffer, int targetStride,
- int numSamples )
-{
- int i;
- for( i=0; i<numSamples; i++ )
- {
- float samp = (*sourceBuffer - 128) * (1.0f / 128.0f);
- *targetBuffer = samp;
- sourceBuffer += sourceStride;
- targetBuffer += targetStride;
- }
-}
-
-/*************************************************************************/
-static void PaConvert_Float32_Int32(
- float *sourceBuffer, int sourceStride,
- int32_t *targetBuffer, int targetStride,
- int numSamples )
-{
- int i;
- for( i=0; i<numSamples; i++ )
- {
- int samp = (int) (*sourceBuffer * 0x7FFFFFFF);
- *targetBuffer = samp;
- sourceBuffer += sourceStride;
- targetBuffer += targetStride;
- }
-}
-
-/*************************************************************************/
-static void PaConvert_Float32_Int32_Clip(
- float *sourceBuffer, int sourceStride,
- int32_t *targetBuffer, int targetStride,
- int numSamples )
-{
- int i;
- for( i=0; i<numSamples; i++ )
- {
- int samp;
- float fs = *sourceBuffer;
- CLIP( fs, -1.0f, 0.999999f );
- samp = (int) (*sourceBuffer * 0x7FFFFFFF);
- *targetBuffer = samp;
- sourceBuffer += sourceStride;
- targetBuffer += targetStride;
- }
-}
-
-/*************************************************************************/
-static void PaConvert_Int32_Float32(
- int32_t *sourceBuffer, int sourceStride,
- float *targetBuffer, int targetStride,
- int numSamples )
-{
- int i;
- for( i=0; i<numSamples; i++ )
- {
- float samp = *sourceBuffer * (1.0f / 0x7FFFFFFF);
- *targetBuffer = samp;
- sourceBuffer += sourceStride;
- targetBuffer += targetStride;
- }
-}
-
-/*************************************************************************/
-static PortAudioConverter *PaConvert_SelectProc( PaSampleFormat sourceFormat,
- PaSampleFormat targetFormat, int ifClip, int ifDither )
-{
- PortAudioConverter *proc = NULL;
- switch( sourceFormat )
- {
- case paUInt8:
- switch( targetFormat )
- {
- case paFloat32:
- proc = (PortAudioConverter *) PaConvert_UInt8_Float32;
- break;
- default:
- break;
- }
- break;
- case paInt8:
- switch( targetFormat )
- {
- case paFloat32:
- proc = (PortAudioConverter *) PaConvert_Int8_Float32;
- break;
- default:
- break;
- }
- break;
- case paInt16:
- switch( targetFormat )
- {
- case paFloat32:
- proc = (PortAudioConverter *) PaConvert_Int16_Float32;
- break;
- default:
- break;
- }
- break;
-
- case paInt32:
- switch( targetFormat )
- {
- case paFloat32:
- proc = (PortAudioConverter *) PaConvert_Int32_Float32;
- break;
- default:
- break;
- }
- break;
-
- case paFloat32:
- switch( targetFormat )
- {
- case paUInt8:
- proc = (PortAudioConverter *) PaConvert_Float32_UInt8;
- break;
- case paInt8:
- if( ifClip && ifDither ) proc = (PortAudioConverter *) PaConvert_Float32_Int8_ClipDither;
- else if( ifClip ) proc = (PortAudioConverter *) PaConvert_Float32_Int8_Clip;
- else if( ifDither ) proc = (PortAudioConverter *) PaConvert_Float32_Int8_Dither;
- else proc = (PortAudioConverter *) PaConvert_Float32_Int8;
- break;
- case paInt16:
- if( ifClip && ifDither ) proc = (PortAudioConverter *) PaConvert_Float32_Int16_ClipDither;
- else if( ifClip ) proc = (PortAudioConverter *) PaConvert_Float32_Int16_Clip;
- else if( ifDither ) proc = (PortAudioConverter *) PaConvert_Float32_Int16_Dither;
- else proc = (PortAudioConverter *) PaConvert_Float32_Int16;
- break;
- case paInt32:
- /* Don't bother dithering a 32 bit integer! */
- if( ifClip ) proc = (PortAudioConverter *) PaConvert_Float32_Int32_Clip;
- else proc = (PortAudioConverter *) PaConvert_Float32_Int32;
- break;
- default:
- break;
- }
- break;
- default:
- break;
- }
- return proc;
-
-}
-
-/*************************************************************************/
-PaError PaConvert_SetupInput( internalPortAudioStream *past,
- PaSampleFormat nativeInputSampleFormat )
-{
- past->past_NativeInputSampleFormat = nativeInputSampleFormat;
- past->past_InputConversionSourceStride = 1;
- past->past_InputConversionTargetStride = 1;
-
- if( nativeInputSampleFormat != past->past_InputSampleFormat )
- {
- int ifDither = (past->past_Flags & paDitherOff) == 0;
- past->past_InputConversionProc = PaConvert_SelectProc( nativeInputSampleFormat,
- past->past_InputSampleFormat, 0, ifDither );
- if( past->past_InputConversionProc == NULL ) return paSampleFormatNotSupported;
- }
- else
- {
- past->past_InputConversionProc = NULL; /* no conversion necessary */
- }
-
- return paNoError;
-}
-
-/*************************************************************************/
-PaError PaConvert_SetupOutput( internalPortAudioStream *past,
- PaSampleFormat nativeOutputSampleFormat )
-{
-
- past->past_NativeOutputSampleFormat = nativeOutputSampleFormat;
- past->past_OutputConversionSourceStride = 1;
- past->past_OutputConversionTargetStride = 1;
-
- if( nativeOutputSampleFormat != past->past_OutputSampleFormat )
- {
- int ifDither = (past->past_Flags & paDitherOff) == 0;
- int ifClip = (past->past_Flags & paClipOff) == 0;
-
- past->past_OutputConversionProc = PaConvert_SelectProc( past->past_OutputSampleFormat,
- nativeOutputSampleFormat, ifClip, ifDither );
- if( past->past_OutputConversionProc == NULL ) return paSampleFormatNotSupported;
- }
- else
- {
- past->past_OutputConversionProc = NULL; /* no conversion necessary */
- }
-
- return paNoError;
-}
-
-/*************************************************************************
-** Called by host code.
-** Convert input from native format to user format,
-** call user code,
-** then convert output to native format.
-** Returns result from user callback.
-*/
-int32_t PaConvert_Process( internalPortAudioStream *past,
- void *nativeInputBuffer,
- void *nativeOutputBuffer )
-{
- int userResult;
- void *inputBuffer = NULL;
- void *outputBuffer = NULL;
-
- /* Get native input data. */
- if( (past->past_NumInputChannels > 0) && (nativeInputBuffer != NULL) )
- {
- if( past->past_InputSampleFormat == past->past_NativeInputSampleFormat )
- {
- /* Already in native format so just read directly from native buffer. */
- inputBuffer = nativeInputBuffer;
- }
- else
- {
- inputBuffer = past->past_InputBuffer;
- /* Convert input data to user format. */
- (*past->past_InputConversionProc)(nativeInputBuffer, past->past_InputConversionSourceStride,
- inputBuffer, past->past_InputConversionTargetStride,
- past->past_FramesPerUserBuffer * past->past_NumInputChannels );
- }
- }
-
- /* Are we doing output? */
- if( (past->past_NumOutputChannels > 0) && (nativeOutputBuffer != NULL) )
- {
- outputBuffer = (past->past_OutputConversionProc == NULL) ?
- nativeOutputBuffer : past->past_OutputBuffer;
- }
- /*
- AddTraceMessage("Pa_CallConvertInt16: inputBuffer = ", (int) inputBuffer );
- AddTraceMessage("Pa_CallConvertInt16: outputBuffer = ", (int) outputBuffer );
- */
- /* Call user callback routine. */
- userResult = past->past_Callback(
- inputBuffer,
- outputBuffer,
- past->past_FramesPerUserBuffer,
- past->past_FrameCount,
- past->past_UserData );
-
- /* Advance frame counter for timestamp. */
- past->past_FrameCount += past->past_FramesPerUserBuffer; // FIXME - should this be in here?
-
- /* Convert to native format if necessary. */
- if( (past->past_OutputConversionProc != NULL ) && (outputBuffer != NULL) )
- {
- (*past->past_OutputConversionProc)( outputBuffer, past->past_OutputConversionSourceStride,
- nativeOutputBuffer, past->past_OutputConversionTargetStride,
- past->past_FramesPerUserBuffer * past->past_NumOutputChannels );
- }
-
- return userResult;
-}
diff --git a/lib/portaudio/pa_host.h b/lib/portaudio/pa_host.h
deleted file mode 100644
index f40da8e..0000000
--- a/lib/portaudio/pa_host.h
+++ /dev/null
@@ -1,189 +0,0 @@
-#ifndef PA_HOST_H
-#define PA_HOST_H
-
-/*
- * $Id$
- * Host dependant internal API for PortAudio
- *
- * Author: Phil Burk <philburk@softsynth.com>
- *
- * PortAudio Portable Real-Time Audio Library
- * Latest Version at: http://www.softsynth.com/portaudio/
- * DirectSound and Macintosh Implementation
- * Copyright (c) 1999-2000 Phil Burk
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files
- * (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * Any person wishing to distribute modifications to the Software is
- * requested to send the modifications to the original developer so that
- * they can be incorporated into the canonical version.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- */
-
-#include "portaudio.h"
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-#ifndef SUPPORT_AUDIO_CAPTURE
-#define SUPPORT_AUDIO_CAPTURE (1)
-#endif
-
-#ifndef int32
- typedef int32_t int32;
-#endif
-#ifndef uint32
- typedef uint32_t uint32;
-#endif
-#ifndef int16
- typedef int16_t int16;
-#endif
-#ifndef uint16
- typedef uint16_t uint16;
-#endif
-
-/* Used to convert between various sample formats. */
-typedef void (PortAudioConverter)(
- void *inputBuffer, int inputStride,
- void *outputBuffer, int outputStride,
- int numSamples );
-
-#define PA_MAGIC (0x18273645)
-
-/************************************************************************************/
-/****************** Structures ******************************************************/
-/************************************************************************************/
-
-typedef struct internalPortAudioStream
-{
- uint32 past_Magic; /* ID for struct to catch bugs. */
-
- /* Begin user specified information. */
- uint32 past_FramesPerUserBuffer;
- uint32 past_NumUserBuffers;
- double past_SampleRate; /* Closest supported sample rate. */
- int past_NumInputChannels;
- int past_NumOutputChannels;
- PaDeviceID past_InputDeviceID;
- PaDeviceID past_OutputDeviceID;
- PaSampleFormat past_InputSampleFormat;
- PaSampleFormat past_OutputSampleFormat;
- PortAudioCallback *past_Callback;
- void *past_UserData;
- uint32 past_Flags;
- /* End user specified information. */
-
- void *past_DeviceData;
- PaSampleFormat past_NativeOutputSampleFormat;
- PaSampleFormat past_NativeInputSampleFormat;
-
- /* Flags for communicating between foreground and background. */
- volatile int past_IsActive; /* Background is still playing. */
- volatile int past_StopSoon; /* Background should keep playing when buffers empty. */
- volatile int past_StopNow; /* Background should stop playing now. */
- /* These buffers are used when the native format does not match the user format. */
- void *past_InputBuffer;
- uint32 past_InputBufferSize; /* Size in bytes of the input buffer. */
- void *past_OutputBuffer;
- uint32 past_OutputBufferSize;
- /* Measurements */
- uint32 past_NumCallbacks;
- PaTimestamp past_FrameCount; /* Frames output to buffer. */
- /* For measuring CPU utilization. */
- double past_AverageInsideCount;
- double past_AverageTotalCount;
- double past_Usage;
- int past_IfLastExitValid;
- /* Format Conversion */
- /* These are setup by PaConversion_Setup() */
- PortAudioConverter *past_InputConversionProc;
- int past_InputConversionSourceStride;
- int past_InputConversionTargetStride;
- PortAudioConverter *past_OutputConversionProc;
- int past_OutputConversionSourceStride;
- int past_OutputConversionTargetStride;
-}
-internalPortAudioStream;
-
-/************************************************************************************/
-/******** These functions must be provided by a platform implementation. ************/
-/************************************************************************************/
-
-PaError PaHost_Init( void );
-PaError PaHost_Term( void );
-
-PaError PaHost_OpenStream( internalPortAudioStream *past );
-PaError PaHost_CloseStream( internalPortAudioStream *past );
-
-PaError PaHost_StartOutput( internalPortAudioStream *past );
-PaError PaHost_StopOutput( internalPortAudioStream *past, int abort );
-PaError PaHost_StartInput( internalPortAudioStream *past );
-PaError PaHost_StopInput( internalPortAudioStream *past, int abort );
-PaError PaHost_StartEngine( internalPortAudioStream *past );
-PaError PaHost_StopEngine( internalPortAudioStream *past, int abort );
-PaError PaHost_StreamActive( internalPortAudioStream *past );
-
-void *PaHost_AllocateFastMemory( int32_t numBytes );
-void PaHost_FreeFastMemory( void *addr, int32_t numBytes );
-
-/* This only called if PA_VALIDATE_RATE IS CALLED. */
-PaError PaHost_ValidateSampleRate( PaDeviceID id, double requestedFrameRate,
- double *closestFrameRatePtr );
-
-/**********************************************************************/
-/************ Common Utility Routines provided by PA ******************/
-/**********************************************************************/
-
-/* PaHost_IsInitialized() returns non-zero if PA is initialized, 0 otherwise */
-int PaHost_IsInitialized( void );
-
-internalPortAudioStream* PaHost_GetStreamRepresentation( PortAudioStream *stream );
-
-int PaHost_FindClosestTableEntry( double allowableError, const double *rateTable,
- int numRates, double frameRate );
-
-int32_t Pa_CallConvertInt16( internalPortAudioStream *past,
- short *nativeInputBuffer,
- short *nativeOutputBuffer );
-
-/* Calculate 2 LSB dither signal with a triangular distribution.
-** Ranged properly for adding to a 32 bit 1.31 fixed point value prior to >>15.
-** Range of output is +/- 65535
-** Multiply by PA_DITHER_SCALE to get a float between -2.0 and 2.0. */
-#define PA_DITHER_BITS (15)
-#define PA_DITHER_SCALE (1.0f / ((1<<PA_DITHER_BITS)-1))
-int32_t PaConvert_TriangularDither( void );
-
-PaError PaConvert_SetupInput( internalPortAudioStream *past,
- PaSampleFormat nativeInputSampleFormat );
-
-PaError PaConvert_SetupOutput( internalPortAudioStream *past,
- PaSampleFormat nativeOutputSampleFormat );
-
-int32_t PaConvert_Process( internalPortAudioStream *past,
- void *nativeInputBuffer,
- void *nativeOutputBuffer );
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-#endif /* PA_HOST_H */
diff --git a/lib/portaudio/pa_lib.c b/lib/portaudio/pa_lib.c
deleted file mode 100644
index a60fc64..0000000
--- a/lib/portaudio/pa_lib.c
+++ /dev/null
@@ -1,806 +0,0 @@
-/*
- * $Id$
- * Portable Audio I/O Library
- * Host Independant Layer
- *
- * Based on the Open Source API proposed by Ross Bencina
- * Copyright (c) 1999-2000 Phil Burk
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files
- * (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * Any person wishing to distribute modifications to the Software is
- * requested to send the modifications to the original developer so that
- * they can be incorporated into the canonical version.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- */
-
-/* Modification History:
- PLB20010422 - apply Mike Berry's changes for CodeWarrior on PC
- PLB20010820 - fix dither and shift for recording PaUInt8 format
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-
-/* PLB20010422 - "memory.h" doesn't work on CodeWarrior for PC. Thanks Mike Berry for the mod. */
-#ifdef _WIN32
-#ifndef __MWERKS__
-#include <memory.h>
-#endif /* __MWERKS__ */
-#else /* !_WIN32 */
-#include <memory.h>
-#endif /* _WIN32 */
-
-#include "portaudio.h"
-#include "pa_host.h"
-#include "pa_trace.h"
-
-/* The reason we might NOT want to validate the rate before opening the stream
- * is because many DirectSound drivers lie about the rates they actually support.
- */
-#define PA_VALIDATE_RATE (0) /* If true validate sample rate against driver info. */
-
-/*
-O- maybe not allocate past_InputBuffer and past_OutputBuffer if not needed for conversion
-*/
-
-#ifndef FALSE
- #define FALSE (0)
- #define TRUE (!FALSE)
-#endif
-
-#define PRINT(x) { printf x; fflush(stdout); }
-#define ERR_RPT(x) PRINT(x)
-#define DBUG(x) /* PRINT(x) */
-#define DBUGX(x) /* PRINT(x) */
-
-static int gInitCount = 0; /* Count number of times Pa_Initialize() called to allow nesting and overlapping. */
-
-static PaError Pa_KillStream( PortAudioStream *stream, int abort );
-
-/***********************************************************************/
-int PaHost_FindClosestTableEntry( double allowableError, const double *rateTable, int numRates, double frameRate )
-{
- double err, minErr = allowableError;
- int i, bestFit = -1;
-
- for( i=0; i<numRates; i++ )
- {
- err = fabs( frameRate - rateTable[i] );
- if( err < minErr )
- {
- minErr = err;
- bestFit = i;
- }
- }
- return bestFit;
-}
-
-/**************************************************************************
-** Make sure sample rate is legal and also convert to enumeration for driver.
-*/
-PaError PaHost_ValidateSampleRate( PaDeviceID id, double requestedFrameRate,
- double *closestFrameRatePtr )
-{
- int32_t bestRateIndex;
- const PaDeviceInfo *pdi;
- pdi = Pa_GetDeviceInfo( id );
- if( pdi == NULL )
- {
- return paInvalidDeviceId;
- }
-
- if( pdi->numSampleRates == -1 )
- {
- /* Is it out of range? */
- if( (requestedFrameRate < pdi->sampleRates[0]) ||
- (requestedFrameRate > pdi->sampleRates[1]) )
- {
- return paInvalidSampleRate;
- }
-
- *closestFrameRatePtr = requestedFrameRate;
- }
- else
- {
- bestRateIndex = PaHost_FindClosestTableEntry( 1.0, pdi->sampleRates, pdi->numSampleRates, requestedFrameRate );
- if( bestRateIndex < 0 ) return paInvalidSampleRate;
- *closestFrameRatePtr = pdi->sampleRates[bestRateIndex];
- }
- return paNoError;
-}
-
-/*************************************************************************/
-PaError Pa_OpenStream(
- PortAudioStream** streamPtrPtr,
- PaDeviceID inputDeviceID,
- int numInputChannels,
- PaSampleFormat inputSampleFormat,
- void *inputDriverInfo,
- PaDeviceID outputDeviceID,
- int numOutputChannels,
- PaSampleFormat outputSampleFormat,
- void *outputDriverInfo,
- double sampleRate,
- uint32_t framesPerBuffer,
- uint32_t numberOfBuffers,
- PaStreamFlags streamFlags,
- PortAudioCallback *callback,
- void *userData )
-{
- internalPortAudioStream *past = NULL;
- PaError result = paNoError;
- int bitsPerInputSample;
- int bitsPerOutputSample;
- /* Print passed parameters. */
- DBUG(("Pa_OpenStream( %p, %d, %d, %d, %p, /* input */ \n",
- streamPtrPtr, inputDeviceID, numInputChannels,
- inputSampleFormat, inputDriverInfo ));
- DBUG((" %d, %d, %d, %p, /* output */\n",
- outputDeviceID, numOutputChannels,
- outputSampleFormat, outputDriverInfo ));
- DBUG((" %g, %d, %d, 0x%x, , %p )\n",
- sampleRate, framesPerBuffer, numberOfBuffers,
- streamFlags, userData ));
-
- /* Check for parameter errors. */
- if( (streamFlags & ~(paClipOff | paDitherOff)) != 0 ) return paInvalidFlag;
- if( streamPtrPtr == NULL ) return paBadStreamPtr;
- if( inputDriverInfo != NULL ) return paHostError; /* REVIEW */
- if( outputDriverInfo != NULL ) return paHostError; /* REVIEW */
- if( (inputDeviceID < 0) && ( outputDeviceID < 0) ) return paInvalidDeviceId;
- if( (outputDeviceID >= Pa_CountDevices()) || (inputDeviceID >= Pa_CountDevices()) )
- {
- return paInvalidDeviceId;
- }
- if( (numInputChannels <= 0) && ( numOutputChannels <= 0) ) return paInvalidChannelCount;
-
-#if SUPPORT_AUDIO_CAPTURE
- if( inputDeviceID >= 0 )
- {
- PaError size = Pa_GetSampleSize( inputSampleFormat );
- if( size < 0 ) return size;
- bitsPerInputSample = 8 * size;
- if( (numInputChannels <= 0) ) return paInvalidChannelCount;
- }
-#else
- if( inputDeviceID >= 0 )
- {
- return paInvalidChannelCount;
- }
-#endif /* SUPPORT_AUDIO_CAPTURE */
- else
- {
- if( numInputChannels > 0 ) return paInvalidChannelCount;
- bitsPerInputSample = 0;
- }
-
- if( outputDeviceID >= 0 )
- {
- PaError size = Pa_GetSampleSize( outputSampleFormat );
- if( size < 0 ) return size;
- bitsPerOutputSample = 8 * size;
- if( (numOutputChannels <= 0) ) return paInvalidChannelCount;
- }
- else
- {
- if( numOutputChannels > 0 ) return paInvalidChannelCount;
- bitsPerOutputSample = 0;
- }
-
- if( callback == NULL ) return paNullCallback;
-
- /* Allocate and clear stream structure. */
- past = (internalPortAudioStream *) PaHost_AllocateFastMemory( sizeof(internalPortAudioStream) );
- if( past == NULL ) return paInsufficientMemory;
- memset( past, 0, sizeof(internalPortAudioStream) );
- AddTraceMessage("Pa_OpenStream: past", (long) past );
-
- past->past_Magic = PA_MAGIC; /* Set ID to catch bugs. */
- past->past_FramesPerUserBuffer = framesPerBuffer;
- past->past_NumUserBuffers = numberOfBuffers; /* NOTE - PaHost_OpenStream() MUST CHECK FOR ZERO! */
- past->past_Callback = callback;
- past->past_UserData = userData;
- past->past_OutputSampleFormat = outputSampleFormat;
- past->past_InputSampleFormat = inputSampleFormat;
- past->past_OutputDeviceID = outputDeviceID;
- past->past_InputDeviceID = inputDeviceID;
- past->past_NumInputChannels = numInputChannels;
- past->past_NumOutputChannels = numOutputChannels;
- past->past_Flags = streamFlags;
-
- /* Check for absurd sample rates. */
- if( (sampleRate < 1000.0) || (sampleRate > 200000.0) )
- {
- result = paInvalidSampleRate;
- goto cleanup;
- }
-
- /* Allocate buffers that may be used for format conversion from user to native buffers. */
- if( numInputChannels > 0 )
- {
-
-#if PA_VALIDATE_RATE
- result = PaHost_ValidateSampleRate( inputDeviceID, sampleRate, &past->past_SampleRate );
- if( result < 0 )
- {
- goto cleanup;
- }
-#else
- past->past_SampleRate = sampleRate;
-#endif
- /* Allocate single Input buffer for passing formatted samples to user callback. */
- past->past_InputBufferSize = framesPerBuffer * numInputChannels * ((bitsPerInputSample+7) / 8);
- past->past_InputBuffer = PaHost_AllocateFastMemory(past->past_InputBufferSize);
- if( past->past_InputBuffer == NULL )
- {
- result = paInsufficientMemory;
- goto cleanup;
- }
- }
- else
- {
- past->past_InputBuffer = NULL;
- }
-
- /* Allocate single Output buffer. */
- if( numOutputChannels > 0 )
- {
-#if PA_VALIDATE_RATE
- result = PaHost_ValidateSampleRate( outputDeviceID, sampleRate, &past->past_SampleRate );
- if( result < 0 )
- {
- goto cleanup;
- }
-#else
- past->past_SampleRate = sampleRate;
-#endif
- past->past_OutputBufferSize = framesPerBuffer * numOutputChannels * ((bitsPerOutputSample+7) / 8);
- past->past_OutputBuffer = PaHost_AllocateFastMemory(past->past_OutputBufferSize);
- if( past->past_OutputBuffer == NULL )
- {
- result = paInsufficientMemory;
- goto cleanup;
- }
- }
- else
- {
- past->past_OutputBuffer = NULL;
- }
-
- result = PaHost_OpenStream( past );
- if( result < 0 ) goto cleanup;
-
- *streamPtrPtr = (void *) past;
-
- return result;
-
-cleanup:
- if( past != NULL ) Pa_CloseStream( past );
- *streamPtrPtr = NULL;
- return result;
-}
-
-
-/*************************************************************************/
-PaError Pa_OpenDefaultStream( PortAudioStream** stream,
- int numInputChannels,
- int numOutputChannels,
- PaSampleFormat sampleFormat,
- double sampleRate,
- uint32_t framesPerBuffer,
- uint32_t numberOfBuffers,
- PortAudioCallback *callback,
- void *userData )
-{
- return Pa_OpenStream(
- stream,
- ((numInputChannels > 0) ? Pa_GetDefaultInputDeviceID() : paNoDevice),
- numInputChannels, sampleFormat, NULL,
- ((numOutputChannels > 0) ? Pa_GetDefaultOutputDeviceID() : paNoDevice),
- numOutputChannels, sampleFormat, NULL,
- sampleRate, framesPerBuffer, numberOfBuffers, paNoFlag, callback, userData );
-}
-
-/*************************************************************************/
-PaError Pa_CloseStream( PortAudioStream* stream)
-{
- PaError result;
- internalPortAudioStream *past;
-
- DBUG(("Pa_CloseStream()\n"));
- if( stream == NULL ) return paBadStreamPtr;
- past = (internalPortAudioStream *) stream;
-
- Pa_AbortStream( past );
- result = PaHost_CloseStream( past );
-
- if( past->past_InputBuffer ) PaHost_FreeFastMemory( past->past_InputBuffer, past->past_InputBufferSize );
- if( past->past_OutputBuffer ) PaHost_FreeFastMemory( past->past_OutputBuffer, past->past_OutputBufferSize );
- PaHost_FreeFastMemory( past, sizeof(internalPortAudioStream) );
-
- return result;
-}
-
-/*************************************************************************/
-PaError Pa_StartStream( PortAudioStream *stream )
-{
- PaError result = paHostError;
- internalPortAudioStream *past;
-
- if( stream == NULL ) return paBadStreamPtr;
- past = (internalPortAudioStream *) stream;
-
- past->past_FrameCount = 0.0;
-
- if( past->past_NumInputChannels > 0 )
- {
- result = PaHost_StartInput( past );
- DBUG(("Pa_StartStream: PaHost_StartInput returned = 0x%X.\n", result));
- if( result < 0 ) goto error;
- }
-
- if( past->past_NumOutputChannels > 0 )
- {
- result = PaHost_StartOutput( past );
- DBUG(("Pa_StartStream: PaHost_StartOutput returned = 0x%X.\n", result));
- if( result < 0 ) goto error;
- }
-
- result = PaHost_StartEngine( past );
- DBUG(("Pa_StartStream: PaHost_StartEngine returned = 0x%X.\n", result));
- if( result < 0 ) goto error;
-
- return paNoError;
-
-error:
- return result;
-}
-
-/*************************************************************************/
-PaError Pa_StopStream( PortAudioStream *stream )
-{
- return Pa_KillStream( stream, 0 );
-}
-
-/*************************************************************************/
-PaError Pa_AbortStream( PortAudioStream *stream )
-{
- return Pa_KillStream( stream, 1 );
-}
-
-/*************************************************************************/
-static PaError Pa_KillStream( PortAudioStream *stream, int abort )
-{
- PaError result = paNoError;
- internalPortAudioStream *past;
-
- DBUG(("Pa_StopStream().\n"));
- if( stream == NULL ) return paBadStreamPtr;
- past = (internalPortAudioStream *) stream;
-
- if( (past->past_NumInputChannels > 0) || (past->past_NumOutputChannels > 0) )
- {
- result = PaHost_StopEngine( past, abort );
- DBUG(("Pa_StopStream: PaHost_StopEngine returned = 0x%X.\n", result));
- if( result < 0 ) goto error;
- }
-
- if( past->past_NumInputChannels > 0 )
- {
- result = PaHost_StopInput( past, abort );
- DBUG(("Pa_StopStream: PaHost_StopInput returned = 0x%X.\n", result));
- if( result != paNoError ) goto error;
- }
-
- if( past->past_NumOutputChannels > 0 )
- {
- result = PaHost_StopOutput( past, abort );
- DBUG(("Pa_StopStream: PaHost_StopOutput returned = 0x%X.\n", result));
- if( result != paNoError ) goto error;
- }
-
-error:
- past->past_Usage = 0;
- past->past_IfLastExitValid = 0;
-
- return result;
-}
-
-/*************************************************************************/
-PaError Pa_StreamActive( PortAudioStream *stream )
-{
- internalPortAudioStream *past;
- if( stream == NULL ) return paBadStreamPtr;
- past = (internalPortAudioStream *) stream;
- return PaHost_StreamActive( past );
-}
-
-/*************************************************************************/
-const char *Pa_GetErrorText( PaError errnum )
-{
- const char *msg;
-
- switch(errnum)
- {
- case paNoError: msg = "Success"; break;
- case paHostError: msg = "Host error."; break;
- case paInvalidChannelCount: msg = "Invalid number of channels."; break;
- case paInvalidSampleRate: msg = "Invalid sample rate."; break;
- case paInvalidDeviceId: msg = "Invalid device ID."; break;
- case paInvalidFlag: msg = "Invalid flag."; break;
- case paSampleFormatNotSupported: msg = "Sample format not supported"; break;
- case paBadIODeviceCombination: msg = "Illegal combination of I/O devices."; break;
- case paInsufficientMemory: msg = "Insufficient memory."; break;
- case paBufferTooBig: msg = "Buffer too big."; break;
- case paBufferTooSmall: msg = "Buffer too small."; break;
- case paNullCallback: msg = "No callback routine specified."; break;
- case paBadStreamPtr: msg = "Invalid stream pointer."; break;
- case paTimedOut : msg = "Wait Timed Out."; break;
- case paInternalError: msg = "Internal PortAudio Error."; break;
- case paDeviceUnavailable: msg = "Device Unavailable."; break;
- default: msg = "Illegal error number."; break;
- }
- return msg;
-}
-
-/*
- Get CPU Load as a fraction of total CPU time.
- A value of 0.5 would imply that PortAudio and the sound generating
- callback was consuming roughly 50% of the available CPU time.
- The amount may vary depending on CPU load.
- This function may be called from the callback function.
-*/
-double Pa_GetCPULoad( PortAudioStream* stream)
-{
- internalPortAudioStream *past;
- if( stream == NULL ) return (double) paBadStreamPtr;
- past = (internalPortAudioStream *) stream;
- return past->past_Usage;
-}
-
-/*************************************************************************/
-internalPortAudioStream* PaHost_GetStreamRepresentation( PortAudioStream *stream )
-{
- internalPortAudioStream* result = (internalPortAudioStream*) stream;
-
- if( result == NULL || result->past_Magic != PA_MAGIC )
- return NULL;
- else
- return result;
-}
-
-/*************************************************************
-** Calculate 2 LSB dither signal with a triangular distribution.
-** Ranged properly for adding to a 32 bit integer prior to >>15.
-** Range of output is +/- 32767
-*/
-#define PA_DITHER_BITS (15)
-#define PA_DITHER_SCALE (1.0f / ((1<<PA_DITHER_BITS)-1))
-int32_t PaConvert_TriangularDither( void )
-{
- static uint32_t previous = 0;
- static uint32_t randSeed1 = 22222;
- static uint32_t randSeed2 = 5555555;
- int32_t current, highPass;
- /* Generate two random numbers. */
- randSeed1 = (randSeed1 * 196314165) + 907633515;
- randSeed2 = (randSeed2 * 196314165) + 907633515;
- /* Generate triangular distribution about 0.
- * Shift before adding to prevent overflow which would skew the distribution.
- * Also shift an extra bit for the high pass filter.
- */
-#define DITHER_SHIFT ((32 - PA_DITHER_BITS) + 1)
- current = (((long)randSeed1)>>DITHER_SHIFT) + (((long)randSeed2)>>DITHER_SHIFT);
- /* High pass filter to reduce audibility. */
- highPass = current - previous;
- previous = current;
- return highPass;
-}
-
-/*************************************************************************
-** Called by host code.
-** Convert input from Int16, call user code, then convert output
-** to Int16 format for native use.
-** Assumes host native format is paInt16.
-** Returns result from user callback.
-*/
-int32_t Pa_CallConvertInt16( internalPortAudioStream *past,
- short *nativeInputBuffer,
- short *nativeOutputBuffer )
-{
- int32_t temp;
- int userResult;
- unsigned int i;
- void *inputBuffer = NULL;
- void *outputBuffer = NULL;
-
-#if SUPPORT_AUDIO_CAPTURE
- /* Get native data from DirectSound. */
- if( (past->past_NumInputChannels > 0) && (nativeInputBuffer != NULL) )
- {
- /* Convert from native format to PA format. */
- unsigned int samplesPerBuffer = past->past_FramesPerUserBuffer * past->past_NumInputChannels;
- switch(past->past_InputSampleFormat)
- {
-
- case paFloat32:
- {
- float *inBufPtr = (float *) past->past_InputBuffer;
- inputBuffer = past->past_InputBuffer;
- for( i=0; i<samplesPerBuffer; i++ )
- {
- inBufPtr[i] = nativeInputBuffer[i] * (1.0f / 32767.0f);
- }
- break;
- }
-
- case paInt32:
- {
- /* Convert 16 bit data to 32 bit integers */
- int *inBufPtr = (int *) past->past_InputBuffer;
- inputBuffer = past->past_InputBuffer;
- for( i=0; i<samplesPerBuffer; i++ )
- {
- inBufPtr[i] = nativeInputBuffer[i] << 16;
- }
- break;
- }
-
- case paInt16:
- {
- /* Already in correct format so don't copy. */
- inputBuffer = nativeInputBuffer;
- break;
- }
-
- case paInt8:
- {
- /* Convert 16 bit data to 8 bit chars */
- char *inBufPtr = (char *) past->past_InputBuffer;
- inputBuffer = past->past_InputBuffer;
- if( past->past_Flags & paDitherOff )
- {
- for( i=0; i<samplesPerBuffer; i++ )
- {
- inBufPtr[i] = (char)(nativeInputBuffer[i] >> 8);
- }
- }
- else
- {
- for( i=0; i<samplesPerBuffer; i++ )
- {
- temp = nativeInputBuffer[i];
- temp += PaConvert_TriangularDither() >> 8; /* PLB20010820 */
- temp = ((temp < -0x8000) ? -0x8000 : ((temp > 0x7FFF) ? 0x7FFF : temp));
- inBufPtr[i] = (char)(temp >> 8);
- }
- }
- break;
- }
-
- case paUInt8:
- {
- /* Convert 16 bit data to 8 bit unsigned chars */
- unsigned char *inBufPtr = (unsigned char *) past->past_InputBuffer;
- inputBuffer = past->past_InputBuffer;
- if( past->past_Flags & paDitherOff )
- {
- for( i=0; i<samplesPerBuffer; i++ )
- {
- inBufPtr[i] = (unsigned char)((nativeInputBuffer[i] >> 8) + 0x80);
- }
- }
- else
- {
- /* If you dither then you have to clip because dithering could push the signal out of range! */
- for( i=0; i<samplesPerBuffer; i++ )
- {
- temp = nativeInputBuffer[i];
- temp += PaConvert_TriangularDither() >> 8; /* PLB20010820 */
- temp = ((temp < -0x8000) ? -0x8000 : ((temp > 0x7FFF) ? 0x7FFF : temp));
- inBufPtr[i] = (unsigned char)((temp>>8) + 0x80); /* PLB20010820 */
- }
- }
- break;
- }
-
- default:
- break;
- }
- }
-#endif /* SUPPORT_AUDIO_CAPTURE */
-
- /* Are we doing output time? */
- if( (past->past_NumOutputChannels > 0) && (nativeOutputBuffer != NULL) )
- {
- /* May already be in native format so just write directly to native buffer. */
- outputBuffer = (past->past_OutputSampleFormat == paInt16) ?
- (void*)nativeOutputBuffer : past->past_OutputBuffer;
- }
- /*
- AddTraceMessage("Pa_CallConvertInt16: inputBuffer = ", (int) inputBuffer );
- AddTraceMessage("Pa_CallConvertInt16: outputBuffer = ", (int) outputBuffer );
- */
- /* Call user callback routine. */
- userResult = past->past_Callback(
- inputBuffer,
- outputBuffer,
- past->past_FramesPerUserBuffer,
- past->past_FrameCount,
- past->past_UserData );
-
- past->past_FrameCount += (PaTimestamp) past->past_FramesPerUserBuffer;
-
- /* Convert to native format if necessary. */
- if( outputBuffer != NULL )
- {
- unsigned int samplesPerBuffer = past->past_FramesPerUserBuffer * past->past_NumOutputChannels;
- switch(past->past_OutputSampleFormat)
- {
- case paFloat32:
- {
- float *outBufPtr = (float *) past->past_OutputBuffer;
- if( past->past_Flags & paDitherOff )
- {
- if( past->past_Flags & paClipOff ) /* NOTHING */
- {
- for( i=0; i<samplesPerBuffer; i++ )
- {
- *nativeOutputBuffer++ = (short) (outBufPtr[i] * (32767.0f));
- }
- }
- else /* CLIP */
- {
- for( i=0; i<samplesPerBuffer; i++ )
- {
- temp = (long)(outBufPtr[i] * 32767.0f);
- *nativeOutputBuffer++ = (short)((temp < -0x8000) ? -0x8000 : ((temp > 0x7FFF) ? 0x7FFF : temp));
- }
- }
- }
- else
- {
- /* If you dither then you have to clip because dithering could push the signal out of range! */
- for( i=0; i<samplesPerBuffer; i++ )
- {
- float dither = PaConvert_TriangularDither()*PA_DITHER_SCALE;
- float dithered = (outBufPtr[i] * (32767.0f)) + dither;
- temp = (long) (dithered);
- *nativeOutputBuffer++ = (short)((temp < -0x8000) ? -0x8000 : ((temp > 0x7FFF) ? 0x7FFF : temp));
- }
- }
- break;
- }
-
- case paInt32:
- {
- int *outBufPtr = (int *) past->past_OutputBuffer;
- if( past->past_Flags & paDitherOff )
- {
- for( i=0; i<samplesPerBuffer; i++ )
- {
- *nativeOutputBuffer++ = (short) (outBufPtr[i] >> 16 );
- }
- }
- else
- {
- for( i=0; i<samplesPerBuffer; i++ )
- {
- /* Shift one bit down before dithering so that we have room for overflow from add. */
- temp = (outBufPtr[i] >> 1) + PaConvert_TriangularDither();
- temp = temp >> 15;
- *nativeOutputBuffer++ = (short)((temp < -0x8000) ? -0x8000 : ((temp > 0x7FFF) ? 0x7FFF : temp));
- }
- }
- break;
- }
-
- case paInt8:
- {
- char *outBufPtr = (char *) past->past_OutputBuffer;
- for( i=0; i<samplesPerBuffer; i++ )
- {
- *nativeOutputBuffer++ = (short) (((int)outBufPtr[i]) << 8);
- }
- break;
- }
-
- case paUInt8:
- {
- unsigned char *outBufPtr = (unsigned char *) past->past_OutputBuffer;
- for( i=0; i<samplesPerBuffer; i++ )
- {
- *nativeOutputBuffer++ = (short) (((int)(outBufPtr[i] - 0x80)) << 8);
- }
- break;
- }
-
- default:
- break;
- }
-
- }
-
- return userResult;
-}
-
-/*************************************************************************/
-PaError Pa_Initialize( void )
-{
- if( gInitCount++ > 0 ) return paNoError;
- ResetTraceMessages();
- return PaHost_Init();
-}
-
-PaError Pa_Terminate( void )
-{
- PaError result = paNoError;
-
- if( gInitCount == 0 ) return paNoError;
- else if( --gInitCount == 0 )
- {
- result = PaHost_Term();
- DumpTraceMessages();
- }
- return result;
-}
-
-int PaHost_IsInitialized()
-{
- return gInitCount;
-}
-
-/*************************************************************************/
-PaError Pa_GetSampleSize( PaSampleFormat format )
-{
- int size;
- switch(format )
- {
-
- case paUInt8:
- case paInt8:
- size = 1;
- break;
-
- case paInt16:
- size = 2;
- break;
-
- case paPackedInt24:
- size = 3;
- break;
-
- case paFloat32:
- case paInt32:
- case paInt24:
- size = 4;
- break;
-
- default:
- size = paSampleFormatNotSupported;
- break;
- }
- return (PaError) size;
-}
-
-
diff --git a/lib/portaudio/pa_mac.c b/lib/portaudio/pa_mac.c
deleted file mode 100644
index 47715e9..0000000
--- a/lib/portaudio/pa_mac.c
+++ /dev/null
@@ -1,1692 +0,0 @@
-/*
- * $Id$
- * Portable Audio I/O Library for Macintosh
- *
- * Based on the Open Source API proposed by Ross Bencina
- * Copyright (c) 1999-2000 Phil Burk
- *
- * Special thanks to Chris Rolfe for his many helpful suggestions, bug fixes,
- * and code contributions.
- * Thanks also to Tue Haste Andersen, Alberto Ricci, Nico Wald,
- * Roelf Toxopeus and Tom Erbe for testing the code and making
- * numerous suggestions.
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files
- * (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * Any person wishing to distribute modifications to the Software is
- * requested to send the modifications to the original developer so that
- * they can be incorporated into the canonical version.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-/* Modification History
- PLB20010415 - ScanInputDevices was setting sDefaultOutputDeviceID instead of sDefaultInputDeviceID
- PLB20010415 - Device Scan was crashing for anything other than siBadSoundInDevice, but some Macs may return other errors!
- PLB20010420 - Fix TIMEOUT in record mode.
- PLB20010420 - Change CARBON_COMPATIBLE to TARGET_API_MAC_CARBON
- PLB20010907 - Pass unused event to WaitNextEvent to prevent Mac OSX crash. Thanks Dominic Mazzoni.
- PLB20010908 - Use requested number of input channels. Thanks Dominic Mazzoni.
- PLB20011009 - Use NewSndCallBackUPP() for CARBON
- PLB20020417 - I used to call Pa_GetMinNumBuffers() which doesn't take into account the
- variable minFramesPerHostBuffer. Now I call PaMac_GetMinNumBuffers() which will
- give lower latency when virtual memory is turned off.
- Thanks Kristoffer Jensen and Georgios Marentakis for spotting this bug.
- PLB20020423 - Use new method to calculate CPU load similar to other ports. Based on num frames calculated.
- Fixed Pa_StreamTime(). Now estimates how many frames have played based on MicroSecond timer.
- Added PA_MAX_USAGE_ALLOWED to prevent Mac from hanging when CPU load approaches 100%.
- PLB20020424 - Fixed return value in Pa_StreamTime
- PLB20020612 - Fix allocation error on Mac 8600 by casting *nameH as uchar* so that we get a proper Str255 length.
-*/
-
-/*
-COMPATIBILITY
-This Macintosh implementation is designed for use with Mac OS 7, 8 and
-9 on PowerMacs, and OS X if compiled with CARBON
-
-OUTPUT
-A circular array of CmpSoundHeaders is used as a queue. For low latency situations
-there will only be two small buffers used. For higher latency, more and larger buffers
-may be used.
-To play the sound we use SndDoCommand() with bufferCmd. Each buffer is followed
-by a callbackCmd which informs us when the buffer has been processsed.
-
-INPUT
-The SndInput Manager SPBRecord call is used for sound input. If only
-input is used, then the PA user callback is called from the Input completion proc.
-For full-duplex, or output only operation, the PA callback is called from the
-HostBuffer output completion proc. In that case, input sound is passed to the
-callback by a simple FIFO.
-
-TODO:
-O- Add support for native sample data formats other than int16.
-O- Review buffer sizing. Should it be based on result of siDeviceBufferInfo query?
-O- Determine default devices somehow.
-*/
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <memory.h>
-#include <math.h>
-#include <config.h>
-
-#ifdef HAVE_DARWIN
-
-/* Mac specific includes */
-#include "OSUtils.h"
-#include <MacTypes.h>
-#include <Math64.h>
-#include <Errors.h>
-#include <Sound.h>
-#include <SoundInput.h>
-#include <SoundComponents.h>
-#include <Devices.h>
-#include <DateTimeUtils.h>
-#include <Timer.h>
-#include <Gestalt.h>
-
-#include "portaudio.h"
-#include "pa_host.h"
-#include "pa_trace.h"
-
-#ifndef FALSE
- #define FALSE (0)
- #define TRUE (!FALSE)
-#endif
-
-/* #define TARGET_API_MAC_CARBON (1) */
-
-/*
- * Define maximum CPU load that will be allowed. User callback will
- * be skipped if load exceeds this limit. This is to prevent the Mac
- * from hanging when the CPU is hogged by the sound thread.
- * On my PowerBook G3, the mac hung when I used 94% of CPU ( usage = 0.94 ).
- */
-#define PA_MAX_USAGE_ALLOWED (0.92)
-
-/* Debugging output macros. */
-#define PRINT(x) { printf x; fflush(stdout); }
-#define ERR_RPT(x) PRINT(x)
-#define DBUG(x) /* PRINT(x) */
-#define DBUGX(x) /* PRINT(x) */
-
-#define MAC_PHYSICAL_FRAMES_PER_BUFFER (512) /* Minimum number of stereo frames per SoundManager double buffer. */
-#define MAC_VIRTUAL_FRAMES_PER_BUFFER (4096) /* Need this many when using Virtual Memory for recording. */
-#define PA_MIN_NUM_HOST_BUFFERS (2)
-#define PA_MAX_NUM_HOST_BUFFERS (16) /* Do not exceed!! */
-#define PA_MAX_DEVICE_INFO (32)
-
-/* Conversions for 16.16 fixed point code. */
-#define DoubleToUnsignedFixed(x) ((UnsignedFixed) ((x) * 65536.0))
-#define UnsignedFixedToDouble(fx) (((double)(fx)) * (1.0/(1<<16)))
-
-/************************************************************************************/
-/****************** Structures ******************************************************/
-/************************************************************************************/
-/* Use for passing buffers from input callback to output callback for processing. */
-typedef struct MultiBuffer
-{
- char *buffers[PA_MAX_NUM_HOST_BUFFERS];
- int numBuffers;
- int nextWrite;
- int nextRead;
-}
-MultiBuffer;
-
-/* Define structure to contain all Macintosh specific data. */
-typedef struct PaHostSoundControl
-{
- UInt64 pahsc_EntryCount;
- double pahsc_InverseMicrosPerHostBuffer; /* 1/Microseconds of real-time audio per user buffer. */
-
- /* Use char instead of Boolean for atomic operation. */
- volatile char pahsc_IsRecording; /* Recording in progress. Set by foreground. Cleared by background. */
- volatile char pahsc_StopRecording; /* Signal sent to background. */
- volatile char pahsc_IfInsideCallback;
- /* Input */
- SPB pahsc_InputParams;
- SICompletionUPP pahsc_InputCompletionProc;
- MultiBuffer pahsc_InputMultiBuffer;
- int32 pahsc_BytesPerInputHostBuffer;
- int32 pahsc_InputRefNum;
- /* Output */
- CmpSoundHeader pahsc_SoundHeaders[PA_MAX_NUM_HOST_BUFFERS];
- int32 pahsc_BytesPerOutputHostBuffer;
- SndChannelPtr pahsc_Channel;
- SndCallBackUPP pahsc_OutputCompletionProc;
- int32 pahsc_NumOutsQueued;
- int32 pahsc_NumOutsPlayed;
- PaTimestamp pahsc_NumFramesDone;
- UInt64 pahsc_WhenFramesDoneIncremented;
- /* Init Time -------------- */
- int32 pahsc_NumHostBuffers;
- int32 pahsc_FramesPerHostBuffer;
- int32 pahsc_UserBuffersPerHostBuffer;
- int32 pahsc_MinFramesPerHostBuffer; /* Can vary depending on virtual memory usage. */
-}
-PaHostSoundControl;
-
-/* Mac specific device information. */
-typedef struct internalPortAudioDevice
-{
- int32_t pad_DeviceRefNum;
- int32_t pad_DeviceBufferSize;
- Component pad_Identifier;
- PaDeviceInfo pad_Info;
-}
-internalPortAudioDevice;
-
-/************************************************************************************/
-/****************** Data ************************************************************/
-/************************************************************************************/
-static int sNumDevices = 0;
-static internalPortAudioDevice sDevices[PA_MAX_DEVICE_INFO] = { 0 };
-static int32 sPaHostError = 0;
-static int sDefaultOutputDeviceID;
-static int sDefaultInputDeviceID;
-
-/************************************************************************************/
-/****************** Prototypes ******************************************************/
-/************************************************************************************/
-static PaError PaMac_TimeSlice( internalPortAudioStream *past, int16 *macOutputBufPtr );
-static PaError PaMac_CallUserLoop( internalPortAudioStream *past, int16 *outPtr );
-static PaError PaMac_RecordNext( internalPortAudioStream *past );
-static void PaMac_StartLoadCalculation( internalPortAudioStream *past );
-static int PaMac_GetMinNumBuffers( int minFramesPerHostBuffer, int framesPerBuffer, double sampleRate );
-static double *PaMac_GetSampleRatesFromHandle ( int numRates, Handle h );
-static PaError PaMac_ScanInputDevices( void );
-static PaError PaMac_ScanOutputDevices( void );
-static PaError PaMac_QueryOutputDeviceInfo( Component identifier, internalPortAudioDevice *ipad );
-static PaError PaMac_QueryInputDeviceInfo( Str255 deviceName, internalPortAudioDevice *ipad );
-static void PaMac_InitSoundHeader( internalPortAudioStream *past, CmpSoundHeader *sndHeader );
-static void PaMac_EndLoadCalculation( internalPortAudioStream *past );
-static void PaMac_PlayNext ( internalPortAudioStream *past, int index );
-static int32_t PaMac_FillNextOutputBuffer( internalPortAudioStream *past, int index );
-static pascal void PaMac_InputCompletionProc(SPBPtr recParams);
-static pascal void PaMac_OutputCompletionProc (SndChannelPtr theChannel, SndCommand * theCmd);
-static PaError PaMac_BackgroundManager( internalPortAudioStream *past, int index );
-int32_t PaHost_GetTotalBufferFrames( internalPortAudioStream *past );
-static int Mac_IsVirtualMemoryOn( void );
-static void PToCString(unsigned char* inString, char* outString);
-static void CToPString(char *inString, unsigned char* outString);
-char *MultiBuffer_GetNextWriteBuffer( MultiBuffer *mbuf );
-char *MultiBuffer_GetNextReadBuffer( MultiBuffer *mbuf );
-int MultiBuffer_GetNextReadIndex( MultiBuffer *mbuf );
-int MultiBuffer_GetNextWriteIndex( MultiBuffer *mbuf );
-int MultiBuffer_IsWriteable( MultiBuffer *mbuf );
-int MultiBuffer_IsReadable( MultiBuffer *mbuf );
-void MultiBuffer_AdvanceReadIndex( MultiBuffer *mbuf );
-void MultiBuffer_AdvanceWriteIndex( MultiBuffer *mbuf );
-
-/*************************************************************************
-** Simple FIFO index control for multiple buffers.
-** Read and Write indices range from 0 to 2N-1.
-** This allows us to distinguish between full and empty.
-*/
-char *MultiBuffer_GetNextWriteBuffer( MultiBuffer *mbuf )
-{
- return mbuf->buffers[mbuf->nextWrite % mbuf->numBuffers];
-}
-char *MultiBuffer_GetNextReadBuffer( MultiBuffer *mbuf )
-{
- return mbuf->buffers[mbuf->nextRead % mbuf->numBuffers];
-}
-int MultiBuffer_GetNextReadIndex( MultiBuffer *mbuf )
-{
- return mbuf->nextRead % mbuf->numBuffers;
-}
-int MultiBuffer_GetNextWriteIndex( MultiBuffer *mbuf )
-{
- return mbuf->nextWrite % mbuf->numBuffers;
-}
-
-int MultiBuffer_IsWriteable( MultiBuffer *mbuf )
-{
- int bufsFull = mbuf->nextWrite - mbuf->nextRead;
- if( bufsFull < 0 ) bufsFull += (2 * mbuf->numBuffers);
- return (bufsFull < mbuf->numBuffers);
-}
-int MultiBuffer_IsReadable( MultiBuffer *mbuf )
-{
- int bufsFull = mbuf->nextWrite - mbuf->nextRead;
- if( bufsFull < 0 ) bufsFull += (2 * mbuf->numBuffers);
- return (bufsFull > 0);
-}
-void MultiBuffer_AdvanceReadIndex( MultiBuffer *mbuf )
-{
- int temp = mbuf->nextRead + 1;
- mbuf->nextRead = (temp >= (2 * mbuf->numBuffers)) ? 0 : temp;
-}
-void MultiBuffer_AdvanceWriteIndex( MultiBuffer *mbuf )
-{
- int temp = mbuf->nextWrite + 1;
- mbuf->nextWrite = (temp >= (2 * mbuf->numBuffers)) ? 0 : temp;
-}
-
-/*************************************************************************
-** String Utility by Chris Rolfe
-*/
-static void PToCString(unsigned char* inString, char* outString)
-{
- int32_t i;
- for(i=0; i<inString[0]; i++) /* convert Pascal to C string */
- outString[i] = inString[i+1];
- outString[i]=0;
-}
-
-/*************************************************************************
-** String Utility by Dominic Mazzoni
-*/
-static void CToPString(char* inString, unsigned char* outString)
-{
- int32_t len = strlen(inString);
- int32_t i;
-
- if (len > 255)
- len = 255;
-
- /* Length is stored in first char of Pascal string */
- outString[0] = (unsigned char)len;
- for(i=0; i<len; i++)
- outString[i+1] = inString[i];
-}
-
-/*************************************************************************/
-PaError PaHost_Term( void )
-{
- int i;
- PaDeviceInfo *dev;
- double *rates;
- /* Free any allocated sample rate arrays. */
- for( i=0; i<sNumDevices; i++ )
- {
- dev = &sDevices[i].pad_Info;
- rates = (double *) dev->sampleRates;
- if( (rates != NULL) ) free( rates ); /* MEM_011 */
- dev->sampleRates = NULL;
- if( dev->name != NULL ) free( (void *) dev->name ); /* MEM_010 */
- dev->name = NULL;
- }
- sNumDevices = 0;
- return paNoError;
-}
-
-/*************************************************************************
- PaHost_Init() is the library initialization function - call this before
- using the library.
-*/
-PaError PaHost_Init( void )
-{
- PaError err;
- NumVersionVariant version;
-
- version.parts = SndSoundManagerVersion();
- DBUG(("SndSoundManagerVersion = 0x%x\n", version.whole));
-
- /* Have we already initialized the device info? */
- err = (PaError) Pa_CountDevices();
- if( err < 0 ) return err;
- else return paNoError;
-}
-
-/*************************************************************************
- PaMac_ScanOutputDevices() queries the properties of all output devices.
-*/
-static PaError PaMac_ScanOutputDevices( void )
-{
- PaError err;
- Component identifier=0;
- ComponentDescription criteria = { kSoundOutputDeviceType, 0, 0, 0, 0 };
- int32_t numComponents, i;
-
- /* Search the system linked list for output components */
- numComponents = CountComponents (&criteria);
- identifier = 0;
- sDefaultOutputDeviceID = sNumDevices; /* FIXME - query somehow */
- for (i = 0; i < numComponents; i++)
- {
- /* passing nil returns first matching component. */
- identifier = FindNextComponent( identifier, &criteria);
- sDevices[sNumDevices].pad_Identifier = identifier;
-
- /* Set up for default OUTPUT devices. */
- err = PaMac_QueryOutputDeviceInfo( identifier, &sDevices[sNumDevices] );
- if( err < 0 ) return err;
- else sNumDevices++;
-
- }
-
- return paNoError;
-}
-
-/*************************************************************************
- PaMac_ScanInputDevices() queries the properties of all input devices.
-*/
-static PaError PaMac_ScanInputDevices( void )
-{
- Str255 deviceName;
- int count;
- Handle iconHandle;
- PaError err;
- OSErr oserr;
- count = 1;
- sDefaultInputDeviceID = sNumDevices; /* FIXME - query somehow */ /* PLB20010415 - was setting sDefaultOutputDeviceID */
- while(true)
- {
- /* Thanks Chris Rolfe and Alberto Ricci for this trick. */
- oserr = SPBGetIndexedDevice(count++, deviceName, &iconHandle);
- DBUG(("PaMac_ScanInputDevices: SPBGetIndexedDevice returned %d\n", oserr ));
-#if 1
- /* PLB20010415 - was giving error for anything other than siBadSoundInDevice, but some Macs may return other errors! */
- if(oserr != noErr) break; /* Some type of error is expected when count > devices */
-#else
- if(oserr == siBadSoundInDevice)
- { /* it's expected when count > devices */
- oserr = noErr;
- break;
- }
- if(oserr != noErr)
- {
- ERR_RPT(("ERROR: SPBGetIndexedDevice(%d,,) returned %d\n", count-1, oserr ));
- sPaHostError = oserr;
- return paHostError;
- }
-#endif
- DisposeHandle(iconHandle); /* Don't need the icon */
-
- err = PaMac_QueryInputDeviceInfo( deviceName, &sDevices[sNumDevices] );
- DBUG(("PaMac_ScanInputDevices: PaMac_QueryInputDeviceInfo returned %d\n", err ));
- if( err < 0 ) return err;
- else if( err == 1 ) sNumDevices++;
- }
-
- return paNoError;
-}
-
-/* Sample rate info returned by using siSampleRateAvailable selector in SPBGetDeviceInfo() */
-/* Thanks to Chris Rolfe for help with this query. */
-#pragma options align=mac68k
-typedef struct
-{
- int16 numRates;
- UnsignedFixed (**rates)[]; /* Handle created by SPBGetDeviceInfo */
-}
-SRateInfo;
-#pragma options align=reset
-
-/*************************************************************************
-** PaMac_QueryOutputDeviceInfo()
-** Query information about a named output device.
-** Clears contents of ipad and writes info based on queries.
-** Return one if OK,
-** zero if device cannot be used,
-** or negative error.
-*/
-static PaError PaMac_QueryOutputDeviceInfo( Component identifier, internalPortAudioDevice *ipad )
-{
- int len;
- OSErr err;
- PaDeviceInfo *dev = &ipad->pad_Info;
- SRateInfo srinfo = {0};
- int numRates;
- ComponentDescription tempD;
- Handle nameH=nil, infoH=nil, iconH=nil;
-
- memset( ipad, 0, sizeof(internalPortAudioDevice) );
-
- dev->structVersion = 1;
- dev->maxInputChannels = 0;
- dev->maxOutputChannels = 2;
- dev->nativeSampleFormats = paInt16; /* FIXME - query to see if 24 or 32 bit data can be handled. */
-
- /* Get sample rates supported. */
- err = GetSoundOutputInfo(identifier, siSampleRateAvailable, (Ptr) &srinfo);
- if(err != noErr)
- {
- ERR_RPT(("Error in PaMac_QueryOutputDeviceInfo: GetSoundOutputInfo siSampleRateAvailable returned %d\n", err ));
- goto error;
- }
- numRates = srinfo.numRates;
- DBUG(("PaMac_QueryOutputDeviceInfo: srinfo.numRates = %d\n", srinfo.numRates ));
- if( numRates == 0 )
- {
- dev->numSampleRates = -1;
- numRates = 2;
- }
- else
- {
- dev->numSampleRates = numRates;
- }
- dev->sampleRates = PaMac_GetSampleRatesFromHandle( numRates, (Handle) srinfo.rates );
- if(dev->sampleRates == NULL)
- {
- DBUG(("PaMac_QueryOutputDeviceInfo: PaMac_GetSampleRatesFromHandle alloc failed.\n"));
- return paInsufficientMemory;
- }
-
- /* SPBGetDeviceInfo created the handle, but it's OUR job to release it. */
- DisposeHandle((Handle) srinfo.rates);
-
- /* Device name */
- /* we pass an existing handle for the component name;
- we don't care about the info (type, subtype, etc.) or icon, so set them to nil */
- DBUG(("PaMac_QueryOutputDeviceInfo: get component name.\n"));
- infoH = nil;
- iconH = nil;
- nameH = NewHandle(0);
- if(nameH == nil) return paInsufficientMemory;
- err = GetComponentInfo(identifier, &tempD, nameH, infoH, iconH);
- if (err)
- {
- ERR_RPT(("Error in PaMac_QueryOutputDeviceInfo: GetComponentInfo returned %d\n", err ));
- goto error;
- }
- /* Cast as uchar* so that we get a proper pascal string length. */
- len = ((unsigned char *)(*nameH))[0] + 1; /* PLB20020612 - fix allocation error on Mac 8600 */
- DBUG(("PaMac_QueryOutputDeviceInfo: new len = %d\n", len ));
-
- dev->name = (char *) malloc(len); /* MEM_010 */
- if( dev->name == NULL )
- {
- DisposeHandle(nameH);
- return paInsufficientMemory;
- }
- else
- {
- PToCString((unsigned char *)(*nameH), (char *) dev->name);
- DisposeHandle(nameH);
- }
-
- DBUG(("PaMac_QueryOutputDeviceInfo: dev->name = %s\n", dev->name ));
- return paNoError;
-
-error:
- sPaHostError = err;
- return paHostError;
-
-}
-
-/*************************************************************************
-** PaMac_QueryInputDeviceInfo()
-** Query information about a named input device.
-** Clears contents of ipad and writes info based on queries.
-** Return one if OK,
-** zero if device cannot be used,
-** or negative error.
-*/
-static PaError PaMac_QueryInputDeviceInfo( Str255 deviceName, internalPortAudioDevice *ipad )
-{
- PaError result = paNoError;
- int len;
- OSErr err;
- int32_t mRefNum = 0;
- int32_t tempL;
- int16 tempS;
- Fixed tempF;
- PaDeviceInfo *dev = &ipad->pad_Info;
- SRateInfo srinfo = {0};
- int numRates;
-
- memset( ipad, 0, sizeof(internalPortAudioDevice) );
- dev->maxOutputChannels = 0;
-
- /* Open device based on name. If device is in use, it may not be able to open in write mode. */
- err = SPBOpenDevice( deviceName, siWritePermission, &mRefNum);
- if (err)
- {
- /* If device is in use, it may not be able to open in write mode so try read mode. */
- err = SPBOpenDevice( deviceName, siReadPermission, &mRefNum);
- if (err)
- {
- ERR_RPT(("Error in PaMac_QueryInputDeviceInfo: SPBOpenDevice returned %d\n", err ));
- sPaHostError = err;
- return paHostError;
- }
- }
-
- /* Define macros for printing out device info. */
-#define PrintDeviceInfo(selector,var) \
- err = SPBGetDeviceInfo(mRefNum, selector, (Ptr) &var); \
- if (err) { \
- DBUG(("query %s failed\n", #selector )); \
- }\
- else { \
- DBUG(("query %s = 0x%x\n", #selector, var )); \
- }
-
- PrintDeviceInfo( siContinuous, tempS );
- PrintDeviceInfo( siAsync, tempS );
- PrintDeviceInfo( siNumberChannels, tempS );
- PrintDeviceInfo( siSampleSize, tempS );
- PrintDeviceInfo( siSampleRate, tempF );
- PrintDeviceInfo( siChannelAvailable, tempS );
- PrintDeviceInfo( siActiveChannels, tempL );
- PrintDeviceInfo( siDeviceBufferInfo, tempL );
-
- err = SPBGetDeviceInfo(mRefNum, siActiveChannels, (Ptr) &tempL);
- if (err == 0) DBUG(("%s = 0x%x\n", "siActiveChannels", tempL ));
- /* Can we use this device? */
- err = SPBGetDeviceInfo(mRefNum, siAsync, (Ptr) &tempS);
- if (err)
- {
- ERR_RPT(("Error in PaMac_QueryInputDeviceInfo: SPBGetDeviceInfo siAsync returned %d\n", err ));
- goto error;
- }
- if( tempS == 0 ) goto useless; /* Does not support async recording so forget about it. */
-
- err = SPBGetDeviceInfo(mRefNum, siChannelAvailable, (Ptr) &tempS);
- if (err)
- {
- ERR_RPT(("Error in PaMac_QueryInputDeviceInfo: SPBGetDeviceInfo siChannelAvailable returned %d\n", err ));
- goto error;
- }
- dev->maxInputChannels = tempS;
-
- /* Get sample rates supported. */
- err = SPBGetDeviceInfo(mRefNum, siSampleRateAvailable, (Ptr) &srinfo);
- if (err)
- {
- ERR_RPT(("Error in PaMac_QueryInputDeviceInfo: SPBGetDeviceInfo siSampleRateAvailable returned %d\n", err ));
- goto error;
- }
-
- numRates = srinfo.numRates;
- DBUG(("numRates = 0x%x\n", numRates ));
- if( numRates == 0 )
- {
- dev->numSampleRates = -1;
- numRates = 2;
- }
- else
- {
- dev->numSampleRates = numRates;
- }
- dev->sampleRates = PaMac_GetSampleRatesFromHandle( numRates, (Handle) srinfo.rates );
- /* SPBGetDeviceInfo created the handle, but it's OUR job to release it. */
- DisposeHandle((Handle) srinfo.rates);
-
- /* Get size of device buffer. */
- err = SPBGetDeviceInfo(mRefNum, siDeviceBufferInfo, (Ptr) &tempL);
- if (err)
- {
- ERR_RPT(("Error in PaMac_QueryInputDeviceInfo: SPBGetDeviceInfo siDeviceBufferInfo returned %d\n", err ));
- goto error;
- }
- ipad->pad_DeviceBufferSize = tempL;
- DBUG(("siDeviceBufferInfo = %d\n", tempL ));
-
- /* Set format based on sample size. */
- err = SPBGetDeviceInfo(mRefNum, siSampleSize, (Ptr) &tempS);
- if (err)
- {
- ERR_RPT(("Error in PaMac_QueryInputDeviceInfo: SPBGetDeviceInfo siSampleSize returned %d\n", err ));
- goto error;
- }
- switch( tempS )
- {
- case 0x0020:
- dev->nativeSampleFormats = paInt32; /* FIXME - warning, code probably won't support this! */
- break;
- case 0x0010:
- default: /* FIXME - What about other formats? */
- dev->nativeSampleFormats = paInt16;
- break;
- }
- DBUG(("nativeSampleFormats = %d\n", dev->nativeSampleFormats ));
-
- /* Device name */
- len = deviceName[0] + 1; /* Get length of Pascal string */
- dev->name = (char *) malloc(len); /* MEM_010 */
- if( dev->name == NULL )
- {
- result = paInsufficientMemory;
- goto cleanup;
- }
- PToCString(deviceName, (char *) dev->name);
- DBUG(("deviceName = %s\n", dev->name ));
- result = (PaError) 1;
- /* All done so close up device. */
-cleanup:
- if( mRefNum ) SPBCloseDevice(mRefNum);
- return result;
-
-error:
- if( mRefNum ) SPBCloseDevice(mRefNum);
- sPaHostError = err;
- return paHostError;
-
-useless:
- if( mRefNum ) SPBCloseDevice(mRefNum);
- return (PaError) 0;
-}
-
-/*************************************************************************
-** Allocate a double array and fill it with listed sample rates.
-*/
-static double * PaMac_GetSampleRatesFromHandle ( int numRates, Handle h )
-{
- OSErr err = noErr;
- SInt8 hState;
- int i;
- UnsignedFixed *fixedRates;
- double *rates = (double *) malloc( numRates * sizeof(double) ); /* MEM_011 */
- if( rates == NULL ) return NULL;
- /* Save and restore handle state as suggested by TechNote at:
- http://developer.apple.com/technotes/tn/tn1122.html
- */
- hState = HGetState (h);
- if (!(err = MemError ()))
- {
- HLock (h);
- if (!(err = MemError ( )))
- {
- fixedRates = (UInt32 *) *h;
- for( i=0; i<numRates; i++ )
- {
- rates[i] = UnsignedFixedToDouble(fixedRates[i]);
- }
-
- HSetState (h,hState);
- err = MemError ( );
- }
- }
- if( err )
- {
- free( rates );
- ERR_RPT(("Error in PaMac_GetSampleRatesFromHandle = %d\n", err ));
- }
- return rates;
-}
-
-/*************************************************************************/
-int Pa_CountDevices()
-{
- PaError err;
- DBUG(("Pa_CountDevices()\n"));
- /* If no devices, go find some. */
- if( sNumDevices <= 0 )
- {
- err = PaMac_ScanOutputDevices();
- if( err != paNoError ) goto error;
- err = PaMac_ScanInputDevices();
- if( err != paNoError ) goto error;
- }
- return sNumDevices;
-
-error:
- PaHost_Term();
- DBUG(("Pa_CountDevices: returns %d\n", err ));
- return err;
-
-}
-
-/*************************************************************************/
-const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceID id )
-{
- if( (id < 0) || ( id >= Pa_CountDevices()) ) return NULL;
- return &sDevices[id].pad_Info;
-}
-/*************************************************************************/
-PaDeviceID Pa_GetDefaultInputDeviceID( void )
-{
- return sDefaultInputDeviceID;
-}
-
-/*************************************************************************/
-PaDeviceID Pa_GetDefaultOutputDeviceID( void )
-{
- return sDefaultOutputDeviceID;
-}
-
-/********************************* BEGIN CPU UTILIZATION MEASUREMENT ****/
-static void PaMac_StartLoadCalculation( internalPortAudioStream *past )
-{
- PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;
- UnsignedWide widePad;
- if( pahsc == NULL ) return;
- /* Query system timer for usage analysis and to prevent overuse of CPU. */
- Microseconds( &widePad );
- pahsc->pahsc_EntryCount = UnsignedWideToUInt64( widePad );
-}
-
-/******************************************************************************
-** Measure fractional CPU load based on real-time it took to calculate
-** buffers worth of output.
-*/
-/**************************************************************************/
-static void PaMac_EndLoadCalculation( internalPortAudioStream *past )
-{
- UnsignedWide widePad;
- UInt64 currentCount;
- int32_t usecsElapsed;
- double newUsage;
- PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;
- if( pahsc == NULL ) return;
-
- /* Measure CPU utilization during this callback. Note that this calculation
- ** assumes that we had the processor the whole time.
- */
-#define LOWPASS_COEFFICIENT_0 (0.95)
-#define LOWPASS_COEFFICIENT_1 (0.99999 - LOWPASS_COEFFICIENT_0)
- Microseconds( &widePad );
- currentCount = UnsignedWideToUInt64( widePad );
-
- usecsElapsed = (long) U64Subtract(currentCount, pahsc->pahsc_EntryCount);
-
- /* Use inverse because it is faster than the divide. */
- newUsage = usecsElapsed * pahsc->pahsc_InverseMicrosPerHostBuffer;
-
- past->past_Usage = (LOWPASS_COEFFICIENT_0 * past->past_Usage) +
- (LOWPASS_COEFFICIENT_1 * newUsage);
-
-}
-
-/***********************************************************************
-** Called by Pa_StartStream()
-*/
-PaError PaHost_StartInput( internalPortAudioStream *past )
-{
- PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;
- pahsc->pahsc_IsRecording = 0;
- pahsc->pahsc_StopRecording = 0;
- pahsc->pahsc_InputMultiBuffer.nextWrite = 0;
- pahsc->pahsc_InputMultiBuffer.nextRead = 0;
- return PaMac_RecordNext( past );
-}
-
-/***********************************************************************
-** Called by Pa_StopStream().
-** May be called during error recovery or cleanup code
-** so protect against NULL pointers.
-*/
-PaError PaHost_StopInput( internalPortAudioStream *past, int abort )
-{
- int32 timeOutMsec;
- PaError result = paNoError;
- OSErr err = 0;
- int32_t mRefNum;
- PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;
- if( pahsc == NULL ) return paNoError;
-
- (void) abort;
-
- mRefNum = pahsc->pahsc_InputRefNum;
-
- DBUG(("PaHost_StopInput: mRefNum = %d\n", mRefNum ));
- if( mRefNum )
- {
- DBUG(("PaHost_StopInput: pahsc_IsRecording = %d\n", pahsc->pahsc_IsRecording ));
- if( pahsc->pahsc_IsRecording )
- {
- /* PLB20010420 - Fix TIMEOUT in record mode. */
- pahsc->pahsc_StopRecording = 1; /* Request that we stop recording. */
- err = SPBStopRecording(mRefNum);
- DBUG(("PaHost_StopInput: then pahsc_IsRecording = %d\n", pahsc->pahsc_IsRecording ));
-
- /* Calculate timeOut longer than longest time it could take to play one buffer. */
- timeOutMsec = (int32) ((1500.0 * pahsc->pahsc_FramesPerHostBuffer) / past->past_SampleRate);
- /* Keep querying sound channel until it is no longer busy playing. */
- while( !err && pahsc->pahsc_IsRecording && (timeOutMsec > 0))
- {
- Pa_Sleep(20);
- timeOutMsec -= 20;
- }
- if( timeOutMsec <= 0 )
- {
- ERR_RPT(("PaHost_StopInput: timed out!\n"));
- return paTimedOut;
- }
- }
- }
- if( err )
- {
- sPaHostError = err;
- result = paHostError;
- }
-
- DBUG(("PaHost_StopInput: finished.\n", mRefNum ));
- return result;
-}
-
-/***********************************************************************/
-static void PaMac_InitSoundHeader( internalPortAudioStream *past, CmpSoundHeader *sndHeader )
-{
- sndHeader->numChannels = past->past_NumOutputChannels;
- sndHeader->sampleRate = DoubleToUnsignedFixed(past->past_SampleRate);
- sndHeader->loopStart = 0;
- sndHeader->loopEnd = 0;
- sndHeader->encode = cmpSH;
- sndHeader->baseFrequency = kMiddleC;
- sndHeader->markerChunk = nil;
- sndHeader->futureUse2 = nil;
- sndHeader->stateVars = nil;
- sndHeader->leftOverSamples = nil;
- sndHeader->compressionID = 0;
- sndHeader->packetSize = 0;
- sndHeader->snthID = 0;
- sndHeader->sampleSize = 8 * sizeof(int16); // FIXME - might be 24 or 32 bits some day;
- sndHeader->sampleArea[0] = 0;
- sndHeader->format = kSoundNotCompressed;
-}
-
-static void SetFramesDone( PaHostSoundControl *pahsc, PaTimestamp framesDone )
-{
- UnsignedWide now;
- Microseconds( &now );
- pahsc->pahsc_NumFramesDone = framesDone;
- pahsc->pahsc_WhenFramesDoneIncremented = UnsignedWideToUInt64( now );
-}
-
-/***********************************************************************/
-PaError PaHost_StartOutput( internalPortAudioStream *past )
-{
- SndCommand pauseCommand;
- SndCommand resumeCommand;
- int i;
- OSErr error;
- PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;
- if( pahsc == NULL ) return paInternalError;
- if( pahsc->pahsc_Channel == NULL ) return paInternalError;
-
- past->past_StopSoon = 0;
- past->past_IsActive = 1;
- pahsc->pahsc_NumOutsQueued = 0;
- pahsc->pahsc_NumOutsPlayed = 0;
-
- SetFramesDone( pahsc, 0.0 );
-
- /* Pause channel so it does not do back ground processing while we are still filling the queue. */
- pauseCommand.cmd = pauseCmd;
- pauseCommand.param1 = pauseCommand.param2 = 0;
- error = SndDoCommand (pahsc->pahsc_Channel, &pauseCommand, true);
- if (noErr != error) goto exit;
-
- /* Queue all of the buffers so we start off full. */
- for (i = 0; i<pahsc->pahsc_NumHostBuffers; i++)
- {
- PaMac_PlayNext( past, i );
- }
-
- /* Resume channel now that the queue is full. */
- resumeCommand.cmd = resumeCmd;
- resumeCommand.param1 = resumeCommand.param2 = 0;
- error = SndDoImmediate( pahsc->pahsc_Channel, &resumeCommand );
- if (noErr != error) goto exit;
-
- return paNoError;
-exit:
- past->past_IsActive = 0;
- sPaHostError = error;
- ERR_RPT(("Error in PaHost_StartOutput: SndDoCommand returned %d\n", error ));
- return paHostError;
-}
-
-/*******************************************************************/
-int32_t PaHost_GetTotalBufferFrames( internalPortAudioStream *past )
-{
- PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;
- return (long) (pahsc->pahsc_NumHostBuffers * pahsc->pahsc_FramesPerHostBuffer);
-}
-
-/***********************************************************************
-** Called by Pa_StopStream().
-** May be called during error recovery or cleanup code
-** so protect against NULL pointers.
-*/
-PaError PaHost_StopOutput( internalPortAudioStream *past, int abort )
-{
- int32 timeOutMsec;
- PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;
- if( pahsc == NULL ) return paNoError;
- if( pahsc->pahsc_Channel == NULL ) return paNoError;
-
- DBUG(("PaHost_StopOutput()\n"));
- if( past->past_IsActive == 0 ) return paNoError;
-
- /* Set flags for callback function to see. */
- if( abort ) past->past_StopNow = 1;
- past->past_StopSoon = 1;
- /* Calculate timeOut longer than longest time it could take to play all buffers. */
- timeOutMsec = (int32) ((1500.0 * PaHost_GetTotalBufferFrames( past )) / past->past_SampleRate);
- /* Keep querying sound channel until it is no longer busy playing. */
- while( past->past_IsActive && (timeOutMsec > 0))
- {
- Pa_Sleep(20);
- timeOutMsec -= 20;
- }
- if( timeOutMsec <= 0 )
- {
- ERR_RPT(("PaHost_StopOutput: timed out!\n"));
- return paTimedOut;
- }
- else return paNoError;
-}
-
-/***********************************************************************/
-PaError PaHost_StartEngine( internalPortAudioStream *past )
-{
- (void) past; /* Prevent unused variable warnings. */
- return paNoError;
-}
-
-/***********************************************************************/
-PaError PaHost_StopEngine( internalPortAudioStream *past, int abort )
-{
- (void) past; /* Prevent unused variable warnings. */
- (void) abort; /* Prevent unused variable warnings. */
- return paNoError;
-}
-/***********************************************************************/
-PaError PaHost_StreamActive( internalPortAudioStream *past )
-{
- PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;
- return (PaError) ( past->past_IsActive + pahsc->pahsc_IsRecording );
-}
-int Mac_IsVirtualMemoryOn( void )
-{
- int32_t attr;
- OSErr result = Gestalt( gestaltVMAttr, &attr );
- DBUG(("gestaltVMAttr : 0x%x\n", attr ));
- return ((attr >> gestaltVMHasPagingControl ) & 1);
-}
-
-/*******************************************************************
-* Determine number of host Buffers
-* and how many User Buffers we can put into each host buffer.
-*/
-static void PaHost_CalcNumHostBuffers( internalPortAudioStream *past )
-{
- PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;
- int32 minNumBuffers;
- int32 minFramesPerHostBuffer;
- int32 minTotalFrames;
- int32 userBuffersPerHostBuffer;
- int32 framesPerHostBuffer;
- int32 numHostBuffers;
-
- minFramesPerHostBuffer = pahsc->pahsc_MinFramesPerHostBuffer;
- minFramesPerHostBuffer = (minFramesPerHostBuffer + 7) & ~7;
- DBUG(("PaHost_CalcNumHostBuffers: minFramesPerHostBuffer = %d\n", minFramesPerHostBuffer ));
-
- /* Determine number of user buffers based on minimum latency. */
- /* PLB20020417 I used to call Pa_GetMinNumBuffers() which doesn't take into account the
- ** variable minFramesPerHostBuffer. Now I call PaMac_GetMinNumBuffers() which will
- ** gove lower latency when virtual memory is turned off. */
- /* minNumBuffers = Pa_GetMinNumBuffers( past->past_FramesPerUserBuffer, past->past_SampleRate ); WRONG */
- minNumBuffers = PaMac_GetMinNumBuffers( minFramesPerHostBuffer, past->past_FramesPerUserBuffer, past->past_SampleRate );
-
- past->past_NumUserBuffers = ( minNumBuffers > past->past_NumUserBuffers ) ? minNumBuffers : past->past_NumUserBuffers;
- DBUG(("PaHost_CalcNumHostBuffers: min past_NumUserBuffers = %d\n", past->past_NumUserBuffers ));
- minTotalFrames = past->past_NumUserBuffers * past->past_FramesPerUserBuffer;
-
- /* We cannot make the buffers too small because they may not get serviced quickly enough. */
- if( (int32) past->past_FramesPerUserBuffer < minFramesPerHostBuffer )
- {
- userBuffersPerHostBuffer =
- (minFramesPerHostBuffer + past->past_FramesPerUserBuffer - 1) /
- past->past_FramesPerUserBuffer;
- }
- else
- {
- userBuffersPerHostBuffer = 1;
- }
- framesPerHostBuffer = past->past_FramesPerUserBuffer * userBuffersPerHostBuffer;
-
- /* Calculate number of host buffers needed. Round up to cover minTotalFrames. */
- numHostBuffers = (minTotalFrames + framesPerHostBuffer - 1) / framesPerHostBuffer;
- /* Make sure we have enough host buffers. */
- if( numHostBuffers < PA_MIN_NUM_HOST_BUFFERS)
- {
- numHostBuffers = PA_MIN_NUM_HOST_BUFFERS;
- }
- else
- {
- /* If we have too many host buffers, try to put more user buffers in a host buffer. */
- while(numHostBuffers > PA_MAX_NUM_HOST_BUFFERS)
- {
- userBuffersPerHostBuffer += 1;
- framesPerHostBuffer = past->past_FramesPerUserBuffer * userBuffersPerHostBuffer;
- numHostBuffers = (minTotalFrames + framesPerHostBuffer - 1) / framesPerHostBuffer;
- }
- }
-
- pahsc->pahsc_UserBuffersPerHostBuffer = userBuffersPerHostBuffer;
- pahsc->pahsc_FramesPerHostBuffer = framesPerHostBuffer;
- pahsc->pahsc_NumHostBuffers = numHostBuffers;
- DBUG(("PaHost_CalcNumHostBuffers: pahsc_UserBuffersPerHostBuffer = %d\n", pahsc->pahsc_UserBuffersPerHostBuffer ));
- DBUG(("PaHost_CalcNumHostBuffers: pahsc_NumHostBuffers = %d\n", pahsc->pahsc_NumHostBuffers ));
- DBUG(("PaHost_CalcNumHostBuffers: pahsc_FramesPerHostBuffer = %d\n", pahsc->pahsc_FramesPerHostBuffer ));
- DBUG(("PaHost_CalcNumHostBuffers: past_NumUserBuffers = %d\n", past->past_NumUserBuffers ));
-}
-
-/*******************************************************************/
-PaError PaHost_OpenStream( internalPortAudioStream *past )
-{
- OSErr err;
- PaError result = paHostError;
- PaHostSoundControl *pahsc;
- int i;
- /* Allocate and initialize host data. */
- pahsc = (PaHostSoundControl *) PaHost_AllocateFastMemory(sizeof(PaHostSoundControl));
- if( pahsc == NULL )
- {
- return paInsufficientMemory;
- }
- past->past_DeviceData = (void *) pahsc;
-
- /* If recording, and virtual memory is turned on, then use bigger buffers to prevent glitches. */
- if( (past->past_NumInputChannels > 0) && Mac_IsVirtualMemoryOn() )
- {
- pahsc->pahsc_MinFramesPerHostBuffer = MAC_VIRTUAL_FRAMES_PER_BUFFER;
- }
- else
- {
- pahsc->pahsc_MinFramesPerHostBuffer = MAC_PHYSICAL_FRAMES_PER_BUFFER;
- }
-
- PaHost_CalcNumHostBuffers( past );
-
- /* Setup constants for CPU load measurement. */
- pahsc->pahsc_InverseMicrosPerHostBuffer = past->past_SampleRate / (1000000.0 * pahsc->pahsc_FramesPerHostBuffer);
-
- /* ------------------ OUTPUT */
- if( past->past_NumOutputChannels > 0 )
- {
- /* Create sound channel to which we can send commands. */
- pahsc->pahsc_Channel = 0L;
- err = SndNewChannel(&pahsc->pahsc_Channel, sampledSynth, 0, nil); /* FIXME - use kUseOptionalOutputDevice if not default. */
- if(err != 0)
- {
- ERR_RPT(("Error in PaHost_OpenStream: SndNewChannel returned 0x%x\n", err ));
- goto error;
- }
-
- /* Install our callback function pointer straight into the sound channel structure */
- /* Use new CARBON name for callback procedure. */
-#if TARGET_API_MAC_CARBON
- pahsc->pahsc_OutputCompletionProc = NewSndCallBackUPP(PaMac_OutputCompletionProc);
-#else
- pahsc->pahsc_OutputCompletionProc = NewSndCallBackProc(PaMac_OutputCompletionProc);
-#endif
-
- pahsc->pahsc_Channel->callBack = pahsc->pahsc_OutputCompletionProc;
-
- pahsc->pahsc_BytesPerOutputHostBuffer = pahsc->pahsc_FramesPerHostBuffer * past->past_NumOutputChannels * sizeof(int16);
- for (i = 0; i<pahsc->pahsc_NumHostBuffers; i++)
- {
- char *buf = (char *)PaHost_AllocateFastMemory(pahsc->pahsc_BytesPerOutputHostBuffer);
- if (buf == NULL)
- {
- ERR_RPT(("Error in PaHost_OpenStream: could not allocate output buffer. Size = \n", pahsc->pahsc_BytesPerOutputHostBuffer ));
- goto memerror;
- }
-
- PaMac_InitSoundHeader( past, &pahsc->pahsc_SoundHeaders[i] );
- pahsc->pahsc_SoundHeaders[i].samplePtr = buf;
- pahsc->pahsc_SoundHeaders[i].numFrames = (unsigned long) pahsc->pahsc_FramesPerHostBuffer;
-
- }
- }
-#ifdef SUPPORT_AUDIO_CAPTURE
- /* ------------------ INPUT */
- /* Use double buffer scheme that matches output. */
- if( past->past_NumInputChannels > 0 )
- {
- int16 tempS;
- int32_t tempL;
- Fixed tempF;
- int32_t mRefNum;
- Str255 namePString;
-#if TARGET_API_MAC_CARBON
- pahsc->pahsc_InputCompletionProc = NewSICompletionUPP((SICompletionProcPtr)PaMac_InputCompletionProc);
-#else
- pahsc->pahsc_InputCompletionProc = NewSICompletionProc((ProcPtr)PaMac_InputCompletionProc);
-#endif
- pahsc->pahsc_BytesPerInputHostBuffer = pahsc->pahsc_FramesPerHostBuffer * past->past_NumInputChannels * sizeof(int16);
- for (i = 0; i<pahsc->pahsc_NumHostBuffers; i++)
- {
- char *buf = (char *) PaHost_AllocateFastMemory(pahsc->pahsc_BytesPerInputHostBuffer);
- if ( buf == NULL )
- {
- ERR_RPT(("PaHost_OpenStream: could not allocate input buffer. Size = \n", pahsc->pahsc_BytesPerInputHostBuffer ));
- goto memerror;
- }
- pahsc->pahsc_InputMultiBuffer.buffers[i] = buf;
- }
- pahsc->pahsc_InputMultiBuffer.numBuffers = pahsc->pahsc_NumHostBuffers;
-
- // err = SPBOpenDevice( (const unsigned char *) &noname, siWritePermission, &mRefNum);
- CToPString((char *)sDevices[past->past_InputDeviceID].pad_Info.name, namePString);
- err = SPBOpenDevice(namePString, siWritePermission, &mRefNum);
-
- if (err) goto error;
- pahsc->pahsc_InputRefNum = mRefNum;
- DBUG(("PaHost_OpenStream: mRefNum = %d\n", mRefNum ));
-
- /* Set input device characteristics. */
- tempS = 1;
- err = SPBSetDeviceInfo(mRefNum, siContinuous, (Ptr) &tempS);
- if (err)
- {
- ERR_RPT(("Error in PaHost_OpenStream: SPBSetDeviceInfo siContinuous returned %d\n", err ));
- goto error;
- }
-
- tempL = 0x03;
- err = SPBSetDeviceInfo(mRefNum, siActiveChannels, (Ptr) &tempL);
- if (err)
- {
- DBUG(("PaHost_OpenStream: setting siActiveChannels returned 0x%x. Error ignored.\n", err ));
- }
-
- /* PLB20010908 - Use requested number of input channels. Thanks Dominic Mazzoni. */
- tempS = past->past_NumInputChannels;
- err = SPBSetDeviceInfo(mRefNum, siNumberChannels, (Ptr) &tempS);
- if (err)
- {
- ERR_RPT(("Error in PaHost_OpenStream: SPBSetDeviceInfo siNumberChannels returned %d\n", err ));
- goto error;
- }
-
- tempF = ((unsigned long)past->past_SampleRate) << 16;
- err = SPBSetDeviceInfo(mRefNum, siSampleRate, (Ptr) &tempF);
- if (err)
- {
- ERR_RPT(("Error in PaHost_OpenStream: SPBSetDeviceInfo siSampleRate returned %d\n", err ));
- goto error;
- }
-
- /* Setup record-parameter block */
- pahsc->pahsc_InputParams.inRefNum = mRefNum;
- pahsc->pahsc_InputParams.milliseconds = 0; // not used
- pahsc->pahsc_InputParams.completionRoutine = pahsc->pahsc_InputCompletionProc;
- pahsc->pahsc_InputParams.interruptRoutine = 0;
- pahsc->pahsc_InputParams.userLong = (long) past;
- pahsc->pahsc_InputParams.unused1 = 0;
- }
-#endif /* SUPPORT_AUDIO_CAPTURE */
- DBUG(("PaHost_OpenStream: complete.\n"));
- return paNoError;
-
-error:
- PaHost_CloseStream( past );
- ERR_RPT(("PaHost_OpenStream: sPaHostError = 0x%x.\n", err ));
- sPaHostError = err;
- return paHostError;
-
-memerror:
- PaHost_CloseStream( past );
- return paInsufficientMemory;
-}
-
-/***********************************************************************
-** Called by Pa_CloseStream().
-** May be called during error recovery or cleanup code
-** so protect against NULL pointers.
-*/
-PaError PaHost_CloseStream( internalPortAudioStream *past )
-{
- PaError result = paNoError;
- OSErr err = 0;
- int i;
- PaHostSoundControl *pahsc;
-
- DBUG(("PaHost_CloseStream( 0x%x )\n", past ));
-
- if( past == NULL ) return paBadStreamPtr;
-
- pahsc = (PaHostSoundControl *) past->past_DeviceData;
- if( pahsc == NULL ) return paNoError;
-
- if( past->past_NumOutputChannels > 0 )
- {
- /* TRUE means flush now instead of waiting for quietCmd to be processed. */
- if( pahsc->pahsc_Channel != NULL ) SndDisposeChannel(pahsc->pahsc_Channel, TRUE);
- {
- for (i = 0; i<pahsc->pahsc_NumHostBuffers; i++)
- {
- Ptr p = (Ptr) pahsc->pahsc_SoundHeaders[i].samplePtr;
- if( p != NULL ) PaHost_FreeFastMemory( p, pahsc->pahsc_BytesPerOutputHostBuffer );
- }
- }
- }
-
- if( past->past_NumInputChannels > 0 )
- {
- if( pahsc->pahsc_InputRefNum )
- {
- err = SPBCloseDevice(pahsc->pahsc_InputRefNum);
- pahsc->pahsc_InputRefNum = 0;
- if( err )
- {
- sPaHostError = err;
- result = paHostError;
- }
- }
- {
- for (i = 0; i<pahsc->pahsc_InputMultiBuffer.numBuffers; i++)
- {
- Ptr p = (Ptr) pahsc->pahsc_InputMultiBuffer.buffers[i];
- if( p != NULL ) PaHost_FreeFastMemory( p, pahsc->pahsc_BytesPerInputHostBuffer );
- }
- }
- }
-
- past->past_DeviceData = NULL;
- PaHost_FreeFastMemory( pahsc, sizeof(PaHostSoundControl) );
-
- DBUG(("PaHost_CloseStream: complete.\n", past ));
- return result;
-}
-/*************************************************************************/
-int Pa_GetMinNumBuffers( int framesPerUserBuffer, double sampleRate )
-{
-/* We use the MAC_VIRTUAL_FRAMES_PER_BUFFER because we might be recording.
-** This routine doesn't have enough information to determine the best value
-** and is being depracated. */
- return PaMac_GetMinNumBuffers( MAC_VIRTUAL_FRAMES_PER_BUFFER, framesPerUserBuffer, sampleRate );
-}
-/*************************************************************************/
-static int PaMac_GetMinNumBuffers( int minFramesPerHostBuffer, int framesPerUserBuffer, double sampleRate )
-{
- int minUserPerHost = ( minFramesPerHostBuffer + framesPerUserBuffer - 1) / framesPerUserBuffer;
- int numBufs = PA_MIN_NUM_HOST_BUFFERS * minUserPerHost;
- if( numBufs < PA_MIN_NUM_HOST_BUFFERS ) numBufs = PA_MIN_NUM_HOST_BUFFERS;
- (void) sampleRate;
- return numBufs;
-}
-
-/*************************************************************************/
-void Pa_Sleep( int32 msec )
-{
- EventRecord event;
- int32 sleepTime, endTime;
- /* Convert to ticks. Round up so we sleep a MINIMUM of msec time. */
- sleepTime = ((msec * 60) + 999) / 1000;
- if( sleepTime < 1 ) sleepTime = 1;
- endTime = TickCount() + sleepTime;
- do
- {
- DBUGX(("Sleep for %d ticks.\n", sleepTime ));
- /* Use WaitNextEvent() to sleep without getting events. */
- /* PLB20010907 - Pass unused event to WaitNextEvent instead of NULL to prevent
- * Mac OSX crash. Thanks Dominic Mazzoni. */
- WaitNextEvent( 0, &event, sleepTime, NULL );
- sleepTime = endTime - TickCount();
- }
- while( sleepTime > 0 );
-}
-/*************************************************************************/
-int32 Pa_GetHostError( void )
-{
- int32 err = sPaHostError;
- sPaHostError = 0;
- return err;
-}
-
-/*************************************************************************
- * Allocate memory that can be accessed in real-time.
- * This may need to be held in physical memory so that it is not
- * paged to virtual memory.
- * This call MUST be balanced with a call to PaHost_FreeFastMemory().
- */
-void *PaHost_AllocateFastMemory( int32_t numBytes )
-{
- void *addr = NewPtrClear( numBytes );
- if( (addr == NULL) || (MemError () != 0) ) return NULL;
-
-#if (TARGET_API_MAC_CARBON == 0)
- if( HoldMemory( addr, numBytes ) != noErr )
- {
- DisposePtr( (Ptr) addr );
- return NULL;
- }
-#endif
- return addr;
-}
-
-/*************************************************************************
- * Free memory that could be accessed in real-time.
- * This call MUST be balanced with a call to PaHost_AllocateFastMemory().
- */
-void PaHost_FreeFastMemory( void *addr, int32_t numBytes )
-{
- if( addr == NULL ) return;
-#if TARGET_API_MAC_CARBON
- (void) numBytes;
-#else
- UnholdMemory( addr, numBytes );
-#endif
- DisposePtr( (Ptr) addr );
-}
-
-/*************************************************************************/
-PaTimestamp Pa_StreamTime( PortAudioStream *stream )
-{
- PaTimestamp framesDone1;
- PaTimestamp framesDone2;
- UInt64 whenIncremented;
- UnsignedWide now;
- UInt64 now64;
- int32_t microsElapsed;
- int32_t framesElapsed;
-
- PaHostSoundControl *pahsc;
- internalPortAudioStream *past = (internalPortAudioStream *) stream;
- if( past == NULL ) return paBadStreamPtr;
- pahsc = (PaHostSoundControl *) past->past_DeviceData;
-
-/* Capture information from audio thread.
- * We have to be careful that we don't get interrupted in the middle.
- * So we grab the pahsc_NumFramesDone twice and make sure it didn't change.
- */
- do
- {
- framesDone1 = pahsc->pahsc_NumFramesDone;
- whenIncremented = pahsc->pahsc_WhenFramesDoneIncremented;
- framesDone2 = pahsc->pahsc_NumFramesDone;
- } while( framesDone1 != framesDone2 );
-
- /* Calculate how many microseconds have elapsed and convert to frames. */
- Microseconds( &now );
- now64 = UnsignedWideToUInt64( now );
- microsElapsed = U64Subtract( now64, whenIncremented );
- framesElapsed = microsElapsed * past->past_SampleRate * 0.000001;
-
- return framesDone1 + framesElapsed;
-}
-
-/**************************************************************************
-** Callback for Input, SPBRecord()
-*/
-int gRecordCounter = 0;
-int gPlayCounter = 0;
-pascal void PaMac_InputCompletionProc(SPBPtr recParams)
-{
- PaError result = paNoError;
- int finished = 1;
- internalPortAudioStream *past;
- PaHostSoundControl *pahsc;
-
- gRecordCounter += 1; /* debug hack to see if engine running */
-
- /* Get our PA data from Mac structure. */
- past = (internalPortAudioStream *) recParams->userLong;
- if( past == NULL ) return;
-
- if( past->past_Magic != PA_MAGIC )
- {
- AddTraceMessage("PaMac_InputCompletionProc: bad MAGIC, past", (long) past );
- AddTraceMessage("PaMac_InputCompletionProc: bad MAGIC, magic", (long) past->past_Magic );
- goto error;
- }
- pahsc = (PaHostSoundControl *) past->past_DeviceData;
- past->past_NumCallbacks += 1;
-
- /* Have we been asked to stop recording? */
- if( (recParams->error == abortErr) || pahsc->pahsc_StopRecording ) goto error;
-
- /* If there are no output channels, then we need to call the user callback function from here.
- * Otherwise we will call the user code during the output completion routine.
- */
- if(past->past_NumOutputChannels == 0)
- {
- SetFramesDone( pahsc,
- pahsc->pahsc_NumFramesDone + pahsc->pahsc_FramesPerHostBuffer );
- result = PaMac_CallUserLoop( past, NULL );
- }
-
- /* Did user code ask us to stop? If not, issue another recording request. */
- if( (result == paNoError) && (pahsc->pahsc_StopRecording == 0) )
- {
- result = PaMac_RecordNext( past );
- if( result != paNoError ) pahsc->pahsc_IsRecording = 0;
- }
- else goto error;
-
- return;
-
-error:
- pahsc->pahsc_IsRecording = 0;
- pahsc->pahsc_StopRecording = 0;
- return;
-}
-
-/***********************************************************************
-** Called by either input or output completion proc.
-** Grabs input data if any present, and calls PA conversion code,
-** that in turn calls user code.
-*/
-static PaError PaMac_CallUserLoop( internalPortAudioStream *past, int16 *outPtr )
-{
- PaError result = paNoError;
- PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;
- int16 *inPtr = NULL;
- int i;
-
-
- /* Advance read index for sound input FIFO here, independantly of record/write process. */
- if(past->past_NumInputChannels > 0)
- {
- if( MultiBuffer_IsReadable( &pahsc->pahsc_InputMultiBuffer ) )
- {
- inPtr = (int16 *) MultiBuffer_GetNextReadBuffer( &pahsc->pahsc_InputMultiBuffer );
- MultiBuffer_AdvanceReadIndex( &pahsc->pahsc_InputMultiBuffer );
- }
- }
-
- /* Call user code enough times to fill buffer. */
- if( (inPtr != NULL) || (outPtr != NULL) )
- {
- PaMac_StartLoadCalculation( past ); /* CPU usage */
-
-#ifdef PA_MAX_USAGE_ALLOWED
- /* If CPU usage exceeds limit, skip user callback to prevent hanging CPU. */
- if( past->past_Usage > PA_MAX_USAGE_ALLOWED )
- {
- past->past_FrameCount += (PaTimestamp) pahsc->pahsc_FramesPerHostBuffer;
- }
- else
-#endif
- {
-
- for( i=0; i<pahsc->pahsc_UserBuffersPerHostBuffer; i++ )
- {
- result = (PaError) Pa_CallConvertInt16( past, inPtr, outPtr );
- if( result != 0)
- {
- /* Recording might be in another process, so tell it to stop with a flag. */
- pahsc->pahsc_StopRecording = pahsc->pahsc_IsRecording;
- break;
- }
- /* Advance sample pointers. */
- if(inPtr != NULL) inPtr += past->past_FramesPerUserBuffer * past->past_NumInputChannels;
- if(outPtr != NULL) outPtr += past->past_FramesPerUserBuffer * past->past_NumOutputChannels;
- }
- }
-
- PaMac_EndLoadCalculation( past );
- }
- return result;
-}
-
-/***********************************************************************
-** Setup next recording buffer in FIFO and issue recording request to Snd Input Manager.
-*/
-static PaError PaMac_RecordNext( internalPortAudioStream *past )
-{
- PaError result = paNoError;
- OSErr err;
- PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;
- /* Get pointer to next buffer to record into. */
- pahsc->pahsc_InputParams.bufferPtr = MultiBuffer_GetNextWriteBuffer( &pahsc->pahsc_InputMultiBuffer );
-
- /* Advance write index if there is room. Otherwise keep writing same buffer. */
- if( MultiBuffer_IsWriteable( &pahsc->pahsc_InputMultiBuffer ) )
- {
- MultiBuffer_AdvanceWriteIndex( &pahsc->pahsc_InputMultiBuffer );
- }
-
- AddTraceMessage("PaMac_RecordNext: bufferPtr", (long) pahsc->pahsc_InputParams.bufferPtr );
- AddTraceMessage("PaMac_RecordNext: nextWrite", pahsc->pahsc_InputMultiBuffer.nextWrite );
-
- /* Setup parameters and issue an asynchronous recording request. */
- pahsc->pahsc_InputParams.bufferLength = pahsc->pahsc_BytesPerInputHostBuffer;
- pahsc->pahsc_InputParams.count = pahsc->pahsc_BytesPerInputHostBuffer;
- err = SPBRecord(&pahsc->pahsc_InputParams, true);
- if( err )
- {
- AddTraceMessage("PaMac_RecordNext: SPBRecord error ", err );
- sPaHostError = err;
- result = paHostError;
- }
- else
- {
- pahsc->pahsc_IsRecording = 1;
- }
- return result;
-}
-
-/**************************************************************************
-** Callback for Output Playback()
-** Return negative error, 0 to continue, 1 to stop.
-*/
-int32_t PaMac_FillNextOutputBuffer( internalPortAudioStream *past, int index )
-{
- PaHostSoundControl *pahsc;
- int32_t result = 0;
- int finished = 1;
- char *outPtr;
-
- gPlayCounter += 1; /* debug hack */
-
- past->past_NumCallbacks += 1;
- pahsc = (PaHostSoundControl *) past->past_DeviceData;
- if( pahsc == NULL ) return -1;
- /* Are we nested?! */
- if( pahsc->pahsc_IfInsideCallback ) return 0;
- pahsc->pahsc_IfInsideCallback = 1;
- /* Get pointer to buffer to fill. */
- outPtr = pahsc->pahsc_SoundHeaders[index].samplePtr;
- /* Combine with any sound input, and call user callback. */
- result = PaMac_CallUserLoop( past, (int16 *) outPtr );
-
- pahsc->pahsc_IfInsideCallback = 0;
- return result;
-}
-
-/*************************************************************************************
-** Called by SoundManager when ready for another buffer.
-*/
-static pascal void PaMac_OutputCompletionProc (SndChannelPtr theChannel, SndCommand * theCallBackCmd)
-{
- internalPortAudioStream *past;
- PaHostSoundControl *pahsc;
- (void) theChannel;
- (void) theCallBackCmd;
-
- /* Get our data from Mac structure. */
- past = (internalPortAudioStream *) theCallBackCmd->param2;
- if( past == NULL ) return;
-
- pahsc = (PaHostSoundControl *) past->past_DeviceData;
- pahsc->pahsc_NumOutsPlayed += 1;
-
- SetFramesDone( pahsc,
- pahsc->pahsc_NumFramesDone + pahsc->pahsc_FramesPerHostBuffer );
-
- PaMac_BackgroundManager( past, theCallBackCmd->param1 );
-}
-
-/*******************************************************************/
-static PaError PaMac_BackgroundManager( internalPortAudioStream *past, int index )
-{
- PaError result = paNoError;
- PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;
- /* Has someone asked us to abort by calling Pa_AbortStream()? */
- if( past->past_StopNow )
- {
- SndCommand command;
- /* Clear the queue of any pending commands. */
- command.cmd = flushCmd;
- command.param1 = command.param2 = 0;
- SndDoImmediate( pahsc->pahsc_Channel, &command );
- /* Then stop currently playing buffer, if any. */
- command.cmd = quietCmd;
- SndDoImmediate( pahsc->pahsc_Channel, &command );
- past->past_IsActive = 0;
- }
- /* Has someone asked us to stop by calling Pa_StopStream()
- * OR has a user callback returned '1' to indicate finished.
- */
- else if( past->past_StopSoon )
- {
- if( (pahsc->pahsc_NumOutsQueued - pahsc->pahsc_NumOutsPlayed) <= 0 )
- {
- past->past_IsActive = 0; /* We're finally done. */
- }
- }
- else
- {
- PaMac_PlayNext( past, index );
- }
- return result;
-}
-
-/*************************************************************************************
-** Fill next buffer with sound and queue it for playback.
-*/
-static void PaMac_PlayNext ( internalPortAudioStream *past, int index )
-{
- OSErr error;
- int32_t result;
- SndCommand playCmd;
- SndCommand callbackCmd;
- PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;
-
- /* If this was the last buffer, or abort requested, then just be done. */
- if ( past->past_StopSoon ) goto done;
-
- /* Load buffer with sound. */
- result = PaMac_FillNextOutputBuffer ( past, index );
- if( result > 0 ) past->past_StopSoon = 1; /* Stop generating audio but wait until buffers play. */
- else if( result < 0 ) goto done;
-
- /* Play the next buffer. */
- playCmd.cmd = bufferCmd;
- playCmd.param1 = 0;
- playCmd.param2 = (long) &pahsc->pahsc_SoundHeaders[ index ];
- error = SndDoCommand (pahsc->pahsc_Channel, &playCmd, true );
- if( error != noErr ) goto gotError;
-
- /* Ask for a callback when it is done. */
- callbackCmd.cmd = callBackCmd;
- callbackCmd.param1 = index;
- callbackCmd.param2 = (long)past;
- error = SndDoCommand (pahsc->pahsc_Channel, &callbackCmd, true );
- if( error != noErr ) goto gotError;
- pahsc->pahsc_NumOutsQueued += 1;
-
- return;
-
-gotError:
- sPaHostError = error;
-done:
- return;
-}
-
-#endif // HAVE_DARWIN
diff --git a/lib/portaudio/pa_mac_core.c b/lib/portaudio/pa_mac_core.c
deleted file mode 100644
index 52c526d..0000000
--- a/lib/portaudio/pa_mac_core.c
+++ /dev/null
@@ -1,2142 +0,0 @@
-/*
- * $Id$
- * pa_mac_core.c
- * Implementation of PortAudio for Mac OS X Core Audio
- *
- * PortAudio Portable Real-Time Audio Library
- * Latest Version at: http://www.portaudio.com
- *
- * Authors: Ross Bencina and Phil Burk
- * Copyright (c) 1999-2002 Ross Bencina and Phil Burk
- *
- * Theory of Operation
- *
- * This code uses the HAL (Hardware Access Layer) of the Apple CoreAudio library.
- * This is the layer closes to the hardware.
- * The HAL layer only supports the native HW supported sample rates.
- * So if the chip only supports 44100 Hz, then the HAL only supports 44100.
- * To provide other rates we use the handy Apple AudioConverter which provides
- * sample rate conversion, mono-to-stereo conversion, and buffer size adaptation.
- *
- * There are four modes of operation:
- * PA_MODE_OUTPUT_ONLY,
- * PA_MODE_INPUT_ONLY,
- * PA_MODE_IO_ONE_DEVICE,
- * PA_MODE_IO_TWO_DEVICES
- *
- * The processing pipeline for PA_MODE_IO_ONE_DEVICE is in one thread:
- *
- * PaOSX_CoreAudioIOCallback() input buffers -> RingBuffer -> input.AudioConverter ->
- * PortAudio callback -> output.AudioConverter -> PaOSX_CoreAudioIOCallback() output buffers
- *
- * For two separate devices, we have to use two separate callbacks.
- * We pass data between them using a RingBuffer FIFO.
- * The processing pipeline for PA_MODE_IO_TWO_DEVICES is split into two threads:
- *
- * PaOSX_CoreAudioInputCallback() input buffers -> RingBuffer
- *
- * RingBuffer -> input.AudioConverter ->
- * PortAudio callback -> output.AudioConverter -> PaOSX_CoreAudioIOCallback() output buffers
- *
- * License
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files
- * (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * Any person wishing to distribute modifications to the Software is
- * requested to send the modifications to the original developer so that
- * they can be incorporated into the canonical version.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * CHANGE HISTORY:
-
- 3.29.2001 - Phil Burk - First pass... converted from Window MME code with help from Darren.
- 3.30.2001 - Darren Gibbs - Added more support for dynamically querying device info.
- 12.7.2001 - Gord Peters - Tweaks to compile on PA V17 and OS X 10.1
- 2.7.2002 - Darren and Phil - fixed isInput so GetProperty works better,
- fixed device queries for numChannels and sampleRates,
- one CoreAudio device now maps to separate input and output PaDevices,
- audio input works if using same CoreAudio device (some HW devices make separate CoreAudio devices).
- 2.22.2002 - Stephane Letz - Explicit cast needed for compilation with Code Warrior 7
- 3.19.2002 - Phil Burk - Added paInt16, paInt8, format using new "pa_common/pa_convert.c" file.
- Return error if opened in mono mode cuz not supported. [Supported 10.12.2002]
- Add support for Pa_GetCPULoad();
- Fixed timestamp in callback and Pa_StreamTime() (Thanks n++k for the advice!)
- Check for invalid sample rates and return an error.
- Check for getenv("PA_MIN_LATENCY_MSEC") to set latency externally.
- Better error checking for invalid channel counts and invalid devices.
- 3.29.2002 - Phil Burk - Fixed Pa_GetCPULoad() for small buffers.
- 3.31.2002 - Phil Burk - Use getrusage() instead of gettimeofday() for CPU Load calculation.
- 10.12.2002 - Phil Burk - Use AudioConverter to allow wide range of sample rates, and mono.
- Use FIFO (from pablio/rinbuffer.h) so that we can pull data through converter.
- Added PaOSX_FixVolumeScalar() to make iMic audible.
- 10.17.2002 - Phil Burk - Support full duplex between two different devices.
- Name internal functions PaOSX_*
- Dumped useless PA_MIN_LATENCY_MSEC environment variable.
- Use kAudioDevicePropertyStreamFormatMatch to determine max channels.
- 02.03.2003 - Phil Burk - always use AudioConverters so that we can adapt when format changes.
- Synchronize with device when format changes.
- 02.13.2003 - Phil Burk - scan for maxChannels because FormatMatch won't tell us.
- 03.05.2003 - Phil Burk and Dominic Mazzoni - interleave and deinterleave multiple
- CoreAudio buffers. Needed for MOTU828 and some other N>2 channel devices.
- See code related to "streamInterleavingBuffer".
- 03.06.2003 - Phil Burk and Ryan Francesconi - fixed numChannels query for MOTU828.
- Handle fact that MOTU828 gives you 8 channels even when you ask for 2!
- 04.06.2003 - Phil Burk - Combine Dominic Mazzoni's technique of using Configuration to query maxChannels
- with old technique of scanning for mormat.
- Increase channel scan by 1 to handle mono USB microphones.
- Do not merge or split channels in AudioConverter to handle 2+2 channels
- of Quattro which has a format of 2 channels.
- 04.07.2003 - Phil Burk - use AudioGetCurrentHostTime instead of getrusage() which can lock threads.
- 04.10.2003 - Phil Burk - fixed pointer bug with input deinterleaving loop.
- Detect and ignore NULL inputData and outputData in CodeAudio callback.
- Overlap creation and deletion of AudioConverters to prevent thread death when device rate changes.
- 04.16.2003 - Phil Burk - Fixed input channel scrambling when numChannels != 2^N. Caused by alignment
- error when filling RingBuffer with 2^N zero bytes.
- 04.26.2003 - Phil Burk - Removed code to turn up volume and unmute to prevent blown eardrums.
- 12.08.2003 - Phil Burk - Move declaration of oldConverter to top of PAOSX_DevicePropertyListener()
- 12.08.2003 - Phil Burk - Removed need for #include "pa_trace.h", just for debug
- 12.09.2003 - Phil Burk - Only change sampleRate or numChannels if we need to improve over
- current setting.
-*/
-
-#include <config.h>
-
-#ifdef HAVE_DARWIN
-
-#include <CoreServices/CoreServices.h>
-#include <CoreAudio/CoreAudio.h>
-#include <sys/time.h>
-#include <sys/resource.h>
-#include <AudioUnit/AudioUnit.h>
-#include <AudioToolbox/DefaultAudioOutput.h>
-#include <AudioToolbox/AudioConverter.h>
-#include <CoreAudio/HostTime.h>
-
-#include "portaudio.h"
-#include "pa_host.h"
-#include "ringbuffer.h"
-
-/************************************************* Configuration ********/
-#define PA_ENABLE_LOAD_MEASUREMENT (1)
-
-/************************************************* Constants ********/
-#define SET_DEVICE_BUFFER_SIZE (1)
-
-/* To trace program, enable TRACE_REALTIME_EVENTS in pa_trace.h */
-#define PA_TRACE_RUN (0)
-#define PA_TRACE_START_STOP (0)
-
-#define PA_MIN_LATENCY_MSEC (20) /* FIXME */
-#define MIN_TIMEOUT_MSEC (3000)
-
-#define PRINT(x) { printf x; fflush(stdout); }
-#define PRINT_ERR( msg, err ) PRINT(( msg ": error = 0x%0lX = '%s'\n", (err), ErrorToString(err)) )
-#define DBUG(x) /* PRINT(x) */
-#define DBUGBACK(x) /* if( sMaxBackgroundErrorMessages-- > 0 ) PRINT(x) */
-#define DBUGX(x)
-
-// define value of isInput passed to CoreAudio routines
-#define IS_INPUT (true)
-#define IS_OUTPUT (false)
-
-typedef enum PaDeviceMode
-{
- PA_MODE_OUTPUT_ONLY,
- PA_MODE_INPUT_ONLY,
- PA_MODE_IO_ONE_DEVICE,
- PA_MODE_IO_TWO_DEVICES
-} PaDeviceMode;
-
-#define PA_USING_OUTPUT (pahsc->mode != PA_MODE_INPUT_ONLY)
-#define PA_USING_INPUT (pahsc->mode != PA_MODE_OUTPUT_ONLY)
-
-/**************************************************************
- * Information needed by PortAudio specific to a CoreAudio device.
- */
-typedef struct PaHostInOut_s
-{
- AudioDeviceID audioDeviceID; /* CoreAudio specific ID */
- int bytesPerUserNativeBuffer; /* User buffer size in native host format. Depends on numChannels. */
- AudioConverterRef converter;
- void *converterBuffer;
- int numChannels;
- /** Used for interleaving or de-interleaving multiple streams for devices like MOTU828. */
- int streamInterleavingBufferLen; /**< size in bytes */
- Float32 *streamInterleavingBuffer;
-} PaHostInOut;
-
-/**************************************************************
- * Structure for internal host specific stream data.
- * This is allocated on a per stream basis.
- */
-typedef struct PaHostSoundControl
-{
- PaHostInOut input;
- PaHostInOut output;
- AudioDeviceID primaryDeviceID;
- PaDeviceMode mode;
- RingBuffer ringBuffer;
- char *ringBufferData;
- Boolean formatListenerCalled;
- /* For measuring CPU utilization. */
- UInt64 entryTime;
- double inverseHostTicksPerBuffer; /* 1/Ticks of real-time audio per user buffer. */
-} PaHostSoundControl;
-
-/**************************************************************
- * Structure for internal extended device info query.
- * There will be one or two PortAudio devices for each Core Audio device:
- * one input and or one output.
- */
-typedef struct PaHostDeviceInfo
-{
- PaDeviceInfo paInfo;
- AudioDeviceID audioDeviceID;
-}
-PaHostDeviceInfo;
-
-/************************************************* Shared Data ********/
-/* FIXME - put Mutex around this shared data. */
-static int sNumPaDevices = 0; /* Total number of PaDeviceInfos */
-static int sNumInputDevices = 0; /* Total number of input PaDeviceInfos */
-static int sNumOutputDevices = 0;
-static int sNumCoreDevices = 0;
-static AudioDeviceID *sCoreDeviceIDs; // Array of Core AudioDeviceIDs
-static PaHostDeviceInfo *sDeviceInfos = NULL;
-static int sDefaultInputDeviceID = paNoDevice;
-static int sDefaultOutputDeviceID = paNoDevice;
-static int sSavedHostError = 0;
-
-static const double supportedSampleRateRange[] = { 8000.0, 96000.0 }; /* FIXME - go to double HW rate. */
-static const char sMapperSuffixInput[] = " - Input";
-static const char sMapperSuffixOutput[] = " - Output";
-
-/* Debug support. */
-//static int sMaxBackgroundErrorMessages = 100;
-//static int sCoverageCounter = 1; // used to check code coverage during validation
-
-/* We index the input devices first, then the output devices. */
-#define LOWEST_INPUT_DEVID (0)
-#define HIGHEST_INPUT_DEVID (sNumInputDevices - 1)
-#define LOWEST_OUTPUT_DEVID (sNumInputDevices)
-#define HIGHEST_OUTPUT_DEVID (sNumPaDevices - 1)
-
-/************************************************* Macros ********/
-
-/************************************************* Prototypes **********/
-
-static PaError PaOSX_QueryDevices( void );
-static int PaOSX_ScanDevices( Boolean isInput );
-static int PaOSX_QueryDeviceInfo( PaHostDeviceInfo *hostDeviceInfo, int coreDeviceIndex, Boolean isInput );
-static PaDeviceID PaOSX_QueryDefaultInputDevice( void );
-static PaDeviceID PaOSX_QueryDefaultOutputDevice( void );
-static void PaOSX_CalcHostBufferSize( internalPortAudioStream *past );
-
-static OSStatus PAOSX_DevicePropertyListener (AudioDeviceID inDevice,
- UInt32 inChannel,
- Boolean isInput,
- AudioDevicePropertyID inPropertyID,
- void* inClientData);
-
-/**********************************************************************/
-/* OS X errors are 4 character ID that can be printed.
- * Note that uses a static pad so result must be printed immediately.
- */
-static OSStatus statusText[2] = { 0, 0 };
-static const char *ErrorToString( OSStatus err )
-{
- const char *str;
-
- switch (err)
- {
- case kAudioHardwareUnspecifiedError:
- str = "kAudioHardwareUnspecifiedError";
- break;
- case kAudioHardwareNotRunningError:
- str = "kAudioHardwareNotRunningError";
- break;
- case kAudioHardwareUnknownPropertyError:
- str = "kAudioHardwareUnknownPropertyError";
- break;
- case kAudioDeviceUnsupportedFormatError:
- str = "kAudioDeviceUnsupportedFormatError";
- break;
- case kAudioHardwareBadPropertySizeError:
- str = "kAudioHardwareBadPropertySizeError";
- break;
- case kAudioHardwareIllegalOperationError:
- str = "kAudioHardwareIllegalOperationError";
- break;
- default:
- statusText[0] = err;
- str = (const char *)statusText;
- break;
- }
-
- return str;
-}
-
-/**********************************************************************/
-static unsigned int32_t RoundUpToNextPowerOf2( unsigned int32_t n )
-{
- int32_t numBits = 0;
- if( ((n-1) & n) == 0) return n; /* Already Power of two. */
- while( n > 0 )
- {
- n= n>>1;
- numBits++;
- }
- return (1<<numBits);
-}
-
-/********************************* BEGIN CPU UTILIZATION MEASUREMENT ****/
-static void Pa_StartUsageCalculation( internalPortAudioStream *past )
-{
- PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;
- if( pahsc == NULL ) return;
- /* Query user CPU timer for usage analysis and to prevent overuse of CPU. */
- pahsc->entryTime = AudioGetCurrentHostTime();
-}
-
-/******************************************************************************
-** Measure fractional CPU load based on real-time it took to calculate
-** buffers worth of output.
-*/
-static void Pa_EndUsageCalculation( internalPortAudioStream *past )
-{
- UInt64 exitTime;
- UInt64 ticksElapsed;
- double newUsage;
-
-#define LOWPASS_COEFFICIENT_0 (0.95)
-#define LOWPASS_COEFFICIENT_1 (0.99999 - LOWPASS_COEFFICIENT_0)
-
- PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;
- if( pahsc == NULL ) return;
-
- exitTime = AudioGetCurrentHostTime();
-
- ticksElapsed = exitTime - pahsc->entryTime;
-
- /* Use inverse because it is faster than the divide. */
- newUsage = ticksElapsed * pahsc->inverseHostTicksPerBuffer;
- /* Low pass filter result. */
- past->past_Usage = (LOWPASS_COEFFICIENT_0 * past->past_Usage) +
- (LOWPASS_COEFFICIENT_1 * newUsage);
-}
-/****************************************** END CPU UTILIZATION *******/
-
-/************************************************************************/
-static PaDeviceID PaOSX_QueryDefaultInputDevice( void )
-{
- OSStatus err = noErr;
- UInt32 count;
- int i;
- AudioDeviceID tempDeviceID = kAudioDeviceUnknown;
- PaDeviceID defaultDeviceID = paNoDevice;
-
- // get the default output device for the HAL
- // it is required to pass the size of the data to be returned
- count = sizeof(tempDeviceID);
- err = AudioHardwareGetProperty( kAudioHardwarePropertyDefaultInputDevice, &count, (void *) &tempDeviceID);
- if (err != noErr) goto error;
-
- // scan input devices to see which one matches this device
- defaultDeviceID = paNoDevice;
- for( i=LOWEST_INPUT_DEVID; i<=HIGHEST_INPUT_DEVID; i++ )
- {
- DBUG(("PaOSX_QueryDefaultInputDevice: i = %d, aDevId = %ld\n", i, sDeviceInfos[i].audioDeviceID ));
- if( sDeviceInfos[i].audioDeviceID == tempDeviceID )
- {
- defaultDeviceID = i;
- break;
- }
- }
-error:
- return defaultDeviceID;
-}
-
-/************************************************************************/
-static PaDeviceID PaOSX_QueryDefaultOutputDevice( void )
-{
- OSStatus err = noErr;
- UInt32 count;
- int i;
- AudioDeviceID tempDeviceID = kAudioDeviceUnknown;
- PaDeviceID defaultDeviceID = paNoDevice;
-
- // get the default output device for the HAL
- // it is required to pass the size of the data to be returned
- count = sizeof(tempDeviceID);
- err = AudioHardwareGetProperty( kAudioHardwarePropertyDefaultOutputDevice, &count, (void *) &tempDeviceID);
- if (err != noErr) goto error;
-
- // scan output devices to see which one matches this device
- defaultDeviceID = paNoDevice;
- for( i=LOWEST_OUTPUT_DEVID; i<=HIGHEST_OUTPUT_DEVID; i++ )
- {
- DBUG(("PaOSX_QueryDefaultOutputDevice: i = %d, aDevId = %ld\n", i, sDeviceInfos[i].audioDeviceID ));
- if( sDeviceInfos[i].audioDeviceID == tempDeviceID )
- {
- defaultDeviceID = i;
- break;
- }
- }
-error:
- return defaultDeviceID;
-}
-
-/******************************************************************/
-static PaError PaOSX_QueryDevices( void )
-{
- OSStatus err = noErr;
- UInt32 outSize;
- Boolean outWritable;
- int numBytes;
-
- // find out how many Core Audio devices there are, if any
- outSize = sizeof(outWritable);
- err = AudioHardwareGetPropertyInfo(kAudioHardwarePropertyDevices, &outSize, &outWritable);
- if (err != noErr)
- {
- PRINT_ERR("Couldn't get info about list of audio devices", err);
- sSavedHostError = err;
- return paHostError;
- }
-
- // calculate the number of device available
- sNumCoreDevices = outSize / sizeof(AudioDeviceID);
-
- // Bail if there aren't any devices
- if (sNumCoreDevices < 1)
- {
- PRINT(("No Devices Available"));
- return paHostError;
- }
-
- // make space for the devices we are about to get
- sCoreDeviceIDs = (AudioDeviceID *)malloc(outSize);
-
- // get an array of AudioDeviceIDs
- err = AudioHardwareGetProperty(kAudioHardwarePropertyDevices, &outSize, (void *)sCoreDeviceIDs);
- if (err != noErr)
- {
- PRINT_ERR("Couldn't get list of audio device IDs", err);
- sSavedHostError = err;
- return paHostError;
- }
-
- // Allocate structures to hold device info pointers.
- // There will be a maximum of two Pa devices per Core Audio device, input and/or output.
- numBytes = sNumCoreDevices * 2 * sizeof(PaHostDeviceInfo);
- sDeviceInfos = (PaHostDeviceInfo *) PaHost_AllocateFastMemory( numBytes );
- if( sDeviceInfos == NULL ) return paInsufficientMemory;
-
- // Scan all the Core Audio devices to see which support input and allocate a
- // PaHostDeviceInfo structure for each one.
- DBUG(("PaOSX_QueryDevices: scan for input ======================\n"));
- PaOSX_ScanDevices( IS_INPUT );
- sNumInputDevices = sNumPaDevices;
- // Now scan all the output devices.
- DBUG(("PaOSX_QueryDevices: scan for output ======================\n"));
- PaOSX_ScanDevices( IS_OUTPUT );
- sNumOutputDevices = sNumPaDevices - sNumInputDevices;
-
- // Figure out which of the devices that we scanned is the default device.
- sDefaultInputDeviceID = PaOSX_QueryDefaultInputDevice();
- sDefaultOutputDeviceID = PaOSX_QueryDefaultOutputDevice();
-
- return paNoError;
-}
-
-
-/*************************************************************************/
-/* Query a device for its sample rate.
- * @return positive rate or 0.0 on error.
- */
-static Float64 PaOSX_GetDeviceSampleRate( AudioDeviceID deviceID, Boolean isInput )
-{
- OSStatus err = noErr;
- AudioStreamBasicDescription formatDesc;
- UInt32 dataSize;
- dataSize = sizeof(formatDesc);
- err = AudioDeviceGetProperty( deviceID, 0, isInput,
- kAudioDevicePropertyStreamFormat, &dataSize, &formatDesc);
- if( err != noErr ) return 0.0;
- else return formatDesc.mSampleRate;
-}
-
-/*************************************************************************/
-/* Allocate a string containing the device name. */
-static char *PaOSX_DeviceNameFromID(AudioDeviceID deviceID, Boolean isInput )
-{
- OSStatus err = noErr;
- UInt32 outSize;
- Boolean outWritable;
- char *deviceName = nil;
-
- // query size of name
- err = AudioDeviceGetPropertyInfo(deviceID, 0, isInput, kAudioDevicePropertyDeviceName, &outSize, &outWritable);
- if (err == noErr)
- {
- deviceName = (char*)malloc( outSize + 1);
- if( deviceName )
- {
- err = AudioDeviceGetProperty(deviceID, 0, isInput, kAudioDevicePropertyDeviceName, &outSize, deviceName);
- if (err != noErr)
- PRINT_ERR("Couldn't get audio device name", err);
- }
- }
-
- return deviceName;
-}
-
-/*************************************************************************
-** Scan all of the Core Audio devices to see which support selected
-** input or output mode.
-** Changes sNumDevices, and fills in sDeviceInfos.
-*/
-static int PaOSX_ScanDevices( Boolean isInput )
-{
- int coreDeviceIndex;
- int result;
- PaHostDeviceInfo *hostDeviceInfo;
- int numAdded = 0;
-
- for( coreDeviceIndex=0; coreDeviceIndex<sNumCoreDevices; coreDeviceIndex++ )
- {
- // try to fill in next PaHostDeviceInfo
- hostDeviceInfo = &sDeviceInfos[sNumPaDevices];
- result = PaOSX_QueryDeviceInfo( hostDeviceInfo, coreDeviceIndex, isInput );
- DBUG(("PaOSX_ScanDevices: paDevId = %d, coreDevId = %d, result = %d\n", sNumPaDevices, coreDeviceIndex, result ));
- if( result > 0 )
- {
- sNumPaDevices += 1; // bump global counter if we got one
- numAdded += 1;
- }
- else if( result < 0 ) return result;
- }
- return numAdded;
-}
-
-/*************************************************************************
-** Determine the maximum number of channels based on the configuration.
-** @return maxChannels or negative error.
-*/
-static int PaOSX_GetMaxChannels_Config( AudioDeviceID devID, Boolean isInput )
-{
- OSStatus err;
- UInt32 outSize;
- Boolean outWritable;
- AudioBufferList *list;
- int numChannels;
- int i;
-
- // Determine maximum number of channels supported.
- // dmazzoni: new method
-
- outSize = 0;
- err = AudioDeviceGetPropertyInfo(devID, 0, isInput,
- kAudioDevicePropertyStreamConfiguration,
- &outSize, &outWritable);
- if ( err != noErr )
- {
- PRINT_ERR("PaOSX_GetMaxChannels_Config: Could not get stream configuration info", err);
- sSavedHostError = err;
- return paHostError;
- }
-
- list = (AudioBufferList *)PaHost_AllocateFastMemory( outSize );
- err = AudioDeviceGetProperty(devID, 0, isInput,
- kAudioDevicePropertyStreamConfiguration,
- &outSize, list);
- if ( err != noErr )
- {
- PRINT_ERR("PaOSX_GetMaxChannels_Config: Could not get stream configuration", err);
- sSavedHostError = err;
- return paHostError;
- }
-
- numChannels = 0;
- for( i=0; i<list->mNumberBuffers; i++ )
- {
- int bufChannels = list->mBuffers[i].mNumberChannels;
- DBUG(("PaOSX_GetMaxChannels_Config: buffer %d has %d channels.\n", i, bufChannels ));
- numChannels += bufChannels;
- }
-
- PaHost_FreeFastMemory( list, outSize );
-
- return numChannels;
-}
-
-/*************************************************************************
-** Determine the maximum number of channels a device will support based on scanning the format.
-** @return maxChannels or negative error.
-*/
-static int PaOSX_GetMaxChannels_Format( AudioDeviceID devID, Boolean isInput )
-{
- OSStatus err;
- UInt32 outSize;
- AudioStreamBasicDescription formatDesc;
- int maxChannels;
- int numChannels;
- Boolean gotMax;
-
- // Scan to find highest matching format.
- // Unfortunately some devices won't just return maxChannels for the match.
- // For example, some 8 channel devices return 2 when given 256 as input.
- gotMax = false;
- maxChannels = 0;
- numChannels = 0;
- while( !gotMax )
- {
-
- memset( &formatDesc, 0, sizeof(formatDesc));
- numChannels = numChannels + 1;
- DBUG(("PaOSX_GetMaxChannels: try numChannels = %d = %d + 1\n",
- numChannels, numChannels ));
- formatDesc.mChannelsPerFrame = numChannels;
- outSize = sizeof(formatDesc);
-
- err = AudioDeviceGetProperty( devID, 0,
- isInput, kAudioDevicePropertyStreamFormatMatch, &outSize, &formatDesc);
-
- DBUG(("PaOSX_GetMaxChannels: err 0x%0x, formatDesc.mChannelsPerFrame= %d\n",
- err, formatDesc.mChannelsPerFrame ));
- if( err != noErr )
- {
- if (numChannels > (maxChannels + 4)) // Try several possibilities above current max
- {
- gotMax = true;
- }
- }
- else
- {
- // This value worked so we have a new candidate for maxChannels.
- if (formatDesc.mChannelsPerFrame > numChannels)
- {
- maxChannels = formatDesc.mChannelsPerFrame;
- }
- else if(formatDesc.mChannelsPerFrame < numChannels)
- {
- if (numChannels > (maxChannels + 4)) // Try several possibilities above current max
- {
- gotMax = true;
- }
- }
- else
- {
- maxChannels = numChannels;
- }
- }
- }
- return maxChannels;
-}
-
-
-
-/*************************************************************************
-** Determine the maximum number of channels a device will support.
-** It is not clear at this point which the better technique so
-** we do both and use the biggest result.
-**
-** @return maxChannels or negative error.
-*/
-static int PaOSX_GetMaxChannels( AudioDeviceID devID, Boolean isInput )
-{
- int maxChannelsFormat;
- int maxChannelsConfig;
- maxChannelsFormat = PaOSX_GetMaxChannels_Format( devID, isInput );
- maxChannelsConfig = PaOSX_GetMaxChannels_Config( devID, isInput );
- return (maxChannelsFormat > maxChannelsConfig) ? maxChannelsFormat : maxChannelsConfig;
-}
-
-/*************************************************************************
-** Try to fill in the device info for this device.
-** Return 1 if a good device that PA can use.
-** Return 0 if not appropriate
-** or return negative error.
-**
-*/
-static int PaOSX_QueryDeviceInfo( PaHostDeviceInfo *hostDeviceInfo, int coreDeviceIndex, Boolean isInput )
-{
- OSStatus err;
- UInt32 outSize;
- AudioStreamBasicDescription formatDesc;
- AudioDeviceID devID;
- PaDeviceInfo *deviceInfo = &hostDeviceInfo->paInfo;
- int maxChannels;
-
- deviceInfo->structVersion = 1;
- deviceInfo->maxInputChannels = 0;
- deviceInfo->maxOutputChannels = 0;
-
- deviceInfo->sampleRates = supportedSampleRateRange; // because we use sample rate converter to get continuous rates
- deviceInfo->numSampleRates = -1;
-
- devID = sCoreDeviceIDs[ coreDeviceIndex ];
- hostDeviceInfo->audioDeviceID = devID;
- DBUG(("PaOSX_QueryDeviceInfo: coreDeviceIndex = %d, devID = %d, isInput = %d\n",
- coreDeviceIndex, (int) devID, isInput ));
-
- // Get data format info from the device.
- outSize = sizeof(formatDesc);
- err = AudioDeviceGetProperty(devID, 0, isInput, kAudioDevicePropertyStreamFormat, &outSize, &formatDesc);
- // This just may not be an appropriate device for input or output so leave quietly.
- if( (err != noErr) || (formatDesc.mChannelsPerFrame == 0) ) goto error;
-
- DBUG(("PaOSX_QueryDeviceInfo: mFormatID = 0x%x\n", (unsigned int) formatDesc.mFormatID));
- DBUG(("PaOSX_QueryDeviceInfo: mFormatFlags = 0x%x\n",(unsigned int) formatDesc.mFormatFlags));
-
- // Right now the Core Audio headers only define one formatID: LinearPCM
- // Apparently LinearPCM must be Float32 for now.
- if( (formatDesc.mFormatID == kAudioFormatLinearPCM) &&
- ((formatDesc.mFormatFlags & kLinearPCMFormatFlagIsFloat) != 0) )
- {
- deviceInfo->nativeSampleFormats = paFloat32;
- }
- else
- {
- PRINT(("PaOSX_QueryDeviceInfo: ERROR - not LinearPCM & Float32!!!\n"));
- return paSampleFormatNotSupported;
- }
-
- maxChannels = PaOSX_GetMaxChannels( devID, isInput );
- if( maxChannels <= 0 ) goto error;
- if( isInput )
- {
- deviceInfo->maxInputChannels = maxChannels;
- }
- else
- {
- deviceInfo->maxOutputChannels = maxChannels;
- }
-
- // Get the device name
- deviceInfo->name = PaOSX_DeviceNameFromID( devID, isInput );
- DBUG(("PaOSX_QueryDeviceInfo: name = %s\n", deviceInfo->name ));
- return 1;
-
-error:
- return 0;
-}
-
-/**********************************************************************/
-static PaError PaOSX_MaybeQueryDevices( void )
-{
- if( sNumPaDevices == 0 )
- {
- return PaOSX_QueryDevices();
- }
- return 0;
-}
-
-static char zeroPad[256] = { 0 };
-
-/**********************************************************************
-** This is the proc that supplies the data to the AudioConverterFillBuffer call.
-** We can pass back arbitrarily sized blocks so if the FIFO region is split
-** just pass back the first half.
-*/
-static OSStatus PaOSX_InputConverterCallbackProc (AudioConverterRef inAudioConverter,
- UInt32* outDataSize,
- void** outData,
- void* inUserData)
-{
- internalPortAudioStream *past = (internalPortAudioStream *) inUserData;
- PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;
- void *dataPtr1;
- int32_t size1;
- void *dataPtr2;
- int32_t size2;
-
- /* Pass contiguous region from FIFO directly to converter. */
- RingBuffer_GetReadRegions( &pahsc->ringBuffer, *outDataSize,
- &dataPtr1, &size1, &dataPtr2, &size2 );
-
- if( size1 > 0 )
- {
- *outData = dataPtr1;
- *outDataSize = size1;
- RingBuffer_AdvanceReadIndex( &pahsc->ringBuffer, size1 );
- DBUGX(("PaOSX_InputConverterCallbackProc: read %ld bytes from FIFO.\n", size1 ));
- }
- else
- {
- DBUGBACK(("PaOSX_InputConverterCallbackProc: got no data!\n"));
- *outData = zeroPad; /* Give it zero data to keep it happy. */
- *outDataSize = sizeof(zeroPad);
- }
- return noErr;
-}
-
-/*****************************************************************************
-** Get audio input, if any, from passed in buffer, or from converter or from FIFO,
-** then run PA callback and output data.
-*/
-static OSStatus PaOSX_LoadAndProcess( internalPortAudioStream *past,
- void *inputBuffer, void *outputBuffer )
-{
- OSStatus err = noErr;
- PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;
-
- if( past->past_StopSoon )
- {
- if( outputBuffer )
- {
- /* Clear remainder of audio buffer if we are waiting for stop. */
- memset( outputBuffer, 0, pahsc->output.bytesPerUserNativeBuffer );
- }
- }
- else
- {
- /* Do we need data from the converted input? */
- if( PA_USING_INPUT )
- {
- UInt32 size = pahsc->input.bytesPerUserNativeBuffer;
- err = AudioConverterFillBuffer(
- pahsc->input.converter,
- PaOSX_InputConverterCallbackProc,
- past,
- &size,
- pahsc->input.converterBuffer);
- if( err != noErr ) return err;
- inputBuffer = pahsc->input.converterBuffer;
- }
-
- /* Measure CPU load. */
-#if PA_ENABLE_LOAD_MEASUREMENT
- Pa_StartUsageCalculation( past );
-#endif
-
- /* Fill part of audio converter buffer by converting input to user format,
- * calling user callback, then converting output to native format. */
- if( PaConvert_Process( past, inputBuffer, outputBuffer ))
- {
- past->past_StopSoon = 1;
- }
-
-#if PA_ENABLE_LOAD_MEASUREMENT
- Pa_EndUsageCalculation( past );
-#endif
-
- }
- return err;
-}
-
-/*****************************************************************************
-** This is the proc that supplies the data to the AudioConverterFillBuffer call
-*/
-static OSStatus PaOSX_OutputConverterCallbackProc (AudioConverterRef inAudioConverter,
- UInt32* outDataSize,
- void** outData,
- void* inUserData)
-{
- internalPortAudioStream *past = (internalPortAudioStream *) inUserData;
- PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;
-
- *outData = pahsc->output.converterBuffer;
- *outDataSize = pahsc->output.bytesPerUserNativeBuffer;
-
- return PaOSX_LoadAndProcess ( past, pahsc->input.converterBuffer, pahsc->output.converterBuffer );
-}
-
-/**********************************************************************
-** If data available, write it to the Ring Buffer so we can
-** pull it from the other side.
-*/
-static OSStatus PaOSX_WriteInputRingBuffer( internalPortAudioStream *past,
- const AudioBufferList* inInputData )
-{
- int numBytes = 0;
- int currentInterleavedChannelIndex;
- int numFramesInInputBuffer;
- int numInterleavedChannels;
- int numChannelsRemaining;
- int i;
- int32_t writeRoom;
- char *inputNativeBufferfPtr = NULL;
- PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;
-
- /* Do we need to deinterleave the buffers first? */
- if( past->past_NumInputChannels != inInputData->mBuffers[0].mNumberChannels )
- {
- numFramesInInputBuffer = inInputData->mBuffers[0].mDataByteSize /
- (sizeof(float) * inInputData->mBuffers[0].mNumberChannels);
-
- numBytes = numFramesInInputBuffer * sizeof(float) * past->past_NumInputChannels;
-
- /* Allocate temporary buffer if needed. */
- if ( (pahsc->input.streamInterleavingBuffer != NULL) &&
- (pahsc->input.streamInterleavingBufferLen < numBytes) )
- {
- PaHost_FreeFastMemory( pahsc->input.streamInterleavingBuffer, pahsc->input.streamInterleavingBufferLen );
- pahsc->input.streamInterleavingBuffer = NULL;
- }
- if ( pahsc->input.streamInterleavingBuffer == NULL )
- {
- pahsc->input.streamInterleavingBufferLen = numBytes;
- pahsc->input.streamInterleavingBuffer = (float *)PaHost_AllocateFastMemory( pahsc->input.streamInterleavingBufferLen );
- }
-
- /* Perform interleaving by writing to temp buffer. */
- currentInterleavedChannelIndex = 0;
- numInterleavedChannels = past->past_NumInputChannels;
- numChannelsRemaining = numInterleavedChannels;
-
- for( i=0; i<inInputData->mNumberBuffers; i++ )
- {
- int j;
- int numBufChannels = inInputData->mBuffers[i].mNumberChannels;
- /* Don't use more than we need or more than we have. */
- int numChannelsUsedInThisBuffer = (numChannelsRemaining < numBufChannels ) ?
- numChannelsRemaining : numBufChannels;
- for( j=0; j<numChannelsUsedInThisBuffer; j++ )
- {
- int k;
- float *dest = &pahsc->input.streamInterleavingBuffer[ currentInterleavedChannelIndex ];
- float *src = &((float *)inInputData->mBuffers[i].mData)[ j ];
- /* Move one channel from CoreAudio buffer to interleaved buffer. */
- for( k=0; k<numFramesInInputBuffer; k++ )
- {
- *dest = *src;
- src += numBufChannels;
- dest += numInterleavedChannels;
- }
- currentInterleavedChannelIndex++;
- }
- numChannelsRemaining -= numChannelsUsedInThisBuffer;
- if( numChannelsRemaining <= 0 ) break;
- }
-
- inputNativeBufferfPtr = (char *)pahsc->input.streamInterleavingBuffer;
- }
- else
- {
- inputNativeBufferfPtr = (char*)inInputData->mBuffers[0].mData;
- numBytes = inInputData->mBuffers[0].mDataByteSize;
- }
-
- writeRoom = RingBuffer_GetWriteAvailable( &pahsc->ringBuffer );
-
- if( numBytes <= writeRoom )
- {
- RingBuffer_Write( &pahsc->ringBuffer, inputNativeBufferfPtr, numBytes );
- DBUGBACK(("PaOSX_WriteInputRingBuffer: wrote %ld bytes to FIFO.\n", numBytes));
- } // FIXME else drop samples on floor, remember overflow???
-
- return noErr;
-}
-
-/**********************************************************************
-** Use any available input buffers by writing to RingBuffer.
-** Process input if PA_MODE_INPUT_ONLY.
-*/
-static OSStatus PaOSX_HandleInput( internalPortAudioStream *past,
- const AudioBufferList* inInputData )
-{
- OSStatus err = noErr;
- PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;
-
- if( inInputData == NULL )
- {
- DBUG(("PaOSX_HandleInput: inInputData == NULL\n"));
- return noErr;
- }
-
- if( inInputData->mNumberBuffers > 0 )
- {
- /* Write to FIFO here if we are only using this callback. */
- if( (pahsc->mode == PA_MODE_INPUT_ONLY) || (pahsc->mode == PA_MODE_IO_ONE_DEVICE) )
- {
- err = PaOSX_WriteInputRingBuffer( past, inInputData );
- if( err != noErr ) goto error;
- }
- }
-
- if( pahsc->mode == PA_MODE_INPUT_ONLY )
- {
- /* Generate user buffers as int32_t as we have a half full input FIFO. */
- int32_t halfSize = pahsc->ringBuffer.bufferSize / 2;
- while( (RingBuffer_GetReadAvailable( &pahsc->ringBuffer ) >= halfSize) &&
- (past->past_StopSoon == 0) )
- {
- err = PaOSX_LoadAndProcess ( past, NULL, NULL );
- if( err != noErr ) goto error;
- }
- }
-
-error:
- return err;
-}
-
-/**********************************************************************
-** Fill any available output buffers.
-*/
-static OSStatus PaOSX_HandleOutput( internalPortAudioStream *past,
- AudioBufferList* outOutputData )
-{
- OSStatus err = noErr;
- void *outputNativeBufferfPtr = NULL;
- PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;
- UInt32 numBytes = 0;
- int numChannelsRemaining;
- Boolean deinterleavingNeeded;
- int numFramesInOutputBuffer;
-
- if( outOutputData == NULL )
- {
- DBUG(("PaOSX_HandleOutput: outOutputData == NULL\n"));
- return noErr;
- }
-
- deinterleavingNeeded = past->past_NumOutputChannels != outOutputData->mBuffers[0].mNumberChannels;
-
- numFramesInOutputBuffer = outOutputData->mBuffers[0].mDataByteSize /
- (sizeof(float) * outOutputData->mBuffers[0].mNumberChannels);
-
- if( pahsc->mode != PA_MODE_INPUT_ONLY )
- {
- /* If we are using output, then we need an empty output buffer. */
- if( outOutputData->mNumberBuffers > 0 )
- {
-
- /* If we have multiple CoreAudio buffers, then we will need to deinterleave after conversion. */
- if( deinterleavingNeeded )
- {
- numBytes = numFramesInOutputBuffer * sizeof(float) * past->past_NumOutputChannels;
-
- /* Free old buffer if we are allocating new one. */
- if ( (pahsc->output.streamInterleavingBuffer != NULL) &&
- (pahsc->output.streamInterleavingBufferLen < numBytes) )
- {
- PaHost_FreeFastMemory( pahsc->output.streamInterleavingBuffer, pahsc->output.streamInterleavingBufferLen );
- pahsc->output.streamInterleavingBuffer = NULL;
- }
- /* Allocate interleaving buffer if needed. */
- if ( pahsc->output.streamInterleavingBuffer == NULL )
- {
- pahsc->output.streamInterleavingBufferLen = numBytes;
- pahsc->output.streamInterleavingBuffer = (float *)PaHost_AllocateFastMemory( pahsc->output.streamInterleavingBufferLen );
- }
-
- outputNativeBufferfPtr = (void*)pahsc->output.streamInterleavingBuffer;
- }
- else
- {
- numBytes = outOutputData->mBuffers[0].mDataByteSize;
- outputNativeBufferfPtr = (void*)outOutputData->mBuffers[0].mData;
- }
-
- /* Pull data from PA user through converter. */
- err = AudioConverterFillBuffer(
- pahsc->output.converter,
- PaOSX_OutputConverterCallbackProc,
- past,
- &numBytes,
- outputNativeBufferfPtr);
- if( err != noErr )
- {
- PRINT_ERR("PaOSX_HandleOutput: AudioConverterFillBuffer failed", err);
- goto error;
- }
-
- /* Deinterleave data from PortAudio and write to multiple CoreAudio buffers. */
- if( deinterleavingNeeded )
- {
- int numInterleavedChannels = past->past_NumOutputChannels;
- int i, currentInterleavedChannelIndex = 0;
- numChannelsRemaining = numInterleavedChannels;
-
- for( i=0; i<outOutputData->mNumberBuffers; i++ )
- {
- int numBufChannels = outOutputData->mBuffers[i].mNumberChannels;
- int j;
- /* Don't use more than we need or more than we have. */
- int numChannelsUsedInThisBuffer = (numChannelsRemaining < numBufChannels ) ?
- numChannelsRemaining : numBufChannels;
-
- for( j=0; j<numChannelsUsedInThisBuffer; j++ )
- {
- int k;
- float *dest = &((float *)outOutputData->mBuffers[i].mData)[ j ];
- float *src = &pahsc->output.streamInterleavingBuffer[ currentInterleavedChannelIndex ];
- /* Move one channel from interleaved buffer to CoreAudio buffer. */
- for( k=0; k<numFramesInOutputBuffer; k++ )
- {
- *dest = *src;
- dest += numBufChannels;
- src += numInterleavedChannels;
- }
- currentInterleavedChannelIndex++;
- }
-
- numChannelsRemaining -= numChannelsUsedInThisBuffer;
- if( numChannelsRemaining <= 0 ) break;
- }
- }
- }
- }
-
-error:
- return err;
-}
-
-/******************************************************************
- * This callback is used when two separate devices are used for input and output.
- * This often happens when using USB devices which present as two devices: input and output.
- * It just writes its data to a FIFO so that it can be read by the main callback
- * proc PaOSX_CoreAudioIOCallback().
- */
-static OSStatus PaOSX_CoreAudioInputCallback (AudioDeviceID inDevice, const AudioTimeStamp* inNow,
- const AudioBufferList* inInputData, const AudioTimeStamp* inInputTime,
- AudioBufferList* outOutputData, const AudioTimeStamp* inOutputTime,
- void* contextPtr)
-{
- OSStatus err = noErr;
- internalPortAudioStream *past = (internalPortAudioStream *) contextPtr;
- PaHostSoundControl *pahsc;
- pahsc = (PaHostSoundControl *) past->past_DeviceData;
-
- /* If there is a FIFO for input then write to it. */
- if( (pahsc->ringBufferData != NULL) && (inInputData != NULL) )
- {
- err = PaOSX_WriteInputRingBuffer( past, inInputData );
- if( err != noErr ) goto error;
- }
-error:
- return err;
-}
-
-/******************************************************************
- * This is the primary callback for CoreAudio.
- * It can handle input and/or output for a single device.
- * It takes input from CoreAudio, converts it and passes it to the
- * PortAudio user callback. Then takes the PA results and passes it
- * back to CoreAudio.
- */
-static OSStatus PaOSX_CoreAudioIOCallback (AudioDeviceID inDevice, const AudioTimeStamp* inNow,
- const AudioBufferList* inInputData, const AudioTimeStamp* inInputTime,
- AudioBufferList* outOutputData, const AudioTimeStamp* inOutputTime,
- void* contextPtr)
-{
- OSStatus err = noErr;
- internalPortAudioStream *past;
- PaHostSoundControl *pahsc;
- past = (internalPortAudioStream *) contextPtr;
- pahsc = (PaHostSoundControl *) past->past_DeviceData;
-
- /* Has someone asked us to abort by calling Pa_AbortStream()? */
- if( past->past_StopNow )
- {
- past->past_IsActive = 0; /* Will cause thread to return. */
- }
- /* Has someone asked us to stop by calling Pa_StopStream()
- * OR has a user callback returned '1' to indicate finished.
- */
- else if( past->past_StopSoon )
- {
- // FIXME - Pretend all done. Should wait for audio to play out but CoreAudio latency very low.
- past->past_IsActive = 0; /* Will cause thread to return. */
- }
- else
- {
- /* use time stamp from CoreAudio if valid */
- if( inOutputTime->mFlags & kAudioTimeStampSampleTimeValid)
- {
- past->past_FrameCount = inOutputTime->mSampleTime;
- }
- else if( inInputTime->mFlags & kAudioTimeStampSampleTimeValid)
- {
- past->past_FrameCount = inInputTime->mSampleTime;
- }
-
- past->past_NumCallbacks += 1;
-
- /* Process full input buffer. */
- err = PaOSX_HandleInput( past, inInputData );
- if( err != 0 ) goto error;
-
- /* Fill up empty output buffers. */
- err = PaOSX_HandleOutput( past, outOutputData );
- if( err != 0 ) goto error;
- }
-
- if( err != 0 ) DBUG(("PaOSX_CoreAudioIOCallback: returns %ld.\n", err ));
-
-error:
- return err;
-}
-
-/*******************************************************************/
-/** Attempt to set device sample rate.
- * This is not critical because we use an AudioConverter but we may
- * get better fidelity if we can avoid resampling.
- *
- * Only set format once because some devices take time to settle.
- * Return flag indicating whether format changed so we know whether to wait
- * for DevicePropertyListener to get called.
- *
- * @return negative error, zero if no change, or one if changed successfully.
- */
-static PaError PaOSX_SetFormat( AudioDeviceID devID, Boolean isInput,
- double desiredRate, int desiredNumChannels )
-{
- AudioStreamBasicDescription formatDesc;
- PaError result = 0;
- OSStatus err;
- UInt32 dataSize;
- Float64 originalRate;
- int originalChannels;
-
- /* Get current device format. This is critical because if we pass
- * zeros for unspecified fields then the iMic device gets switched to a 16 bit
- * integer format!!! I don't know if this is a Mac bug or not. But it only
- * started happening when I upgraded from OS X V10.1 to V10.2 (Jaguar).
- */
- dataSize = sizeof(formatDesc);
- err = AudioDeviceGetProperty( devID, 0, isInput,
- kAudioDevicePropertyStreamFormat, &dataSize, &formatDesc);
- if( err != noErr )
- {
- PRINT_ERR("PaOSX_SetFormat: Could not get format.", err);
- sSavedHostError = err;
- return paHostError;
- }
-
- originalRate = formatDesc.mSampleRate;
- originalChannels = formatDesc.mChannelsPerFrame;
-
- // Changing the format can mess up other apps.
- // So only change the format if the original format
- // has a lower sample rate, or fewer channels, than the desired format.
- if( (originalRate < desiredRate) || (originalChannels < desiredNumChannels) )
- {
- DBUG(("PaOSX_SetFormat: try to change sample rate from %f to %f.\n", originalRate, desiredRate ));
- DBUG(("PaOSX_SetFormat: try to set number of channels %d to %d\n", originalChannels, desiredNumChannels));
-
- formatDesc.mSampleRate = desiredRate;
- formatDesc.mChannelsPerFrame = desiredNumChannels;
- formatDesc.mBytesPerFrame = formatDesc.mChannelsPerFrame * sizeof(float);
- formatDesc.mBytesPerPacket = formatDesc.mBytesPerFrame * formatDesc.mFramesPerPacket;
-
- err = AudioDeviceSetProperty( devID, 0, 0,
- isInput, kAudioDevicePropertyStreamFormat, sizeof(formatDesc), &formatDesc);
- if (err != noErr)
- {
- /* Could not set to desired rate so query for closest match. */
- dataSize = sizeof(formatDesc);
- err = AudioDeviceGetProperty( devID, 0,
- isInput, kAudioDevicePropertyStreamFormatMatch, &dataSize, &formatDesc);
-
- DBUG(("PaOSX_SetFormat: closest rate is %f.\n", formatDesc.mSampleRate ));
- DBUG(("PaOSX_SetFormat: closest numChannels is %d.\n", (int)formatDesc.mChannelsPerFrame ));
- // Set to closest if different from original.
- if( (err == noErr) &&
- ((originalRate != formatDesc.mSampleRate) ||
- (originalChannels != formatDesc.mChannelsPerFrame)) )
- {
- err = AudioDeviceSetProperty( devID, 0, 0,
- isInput, kAudioDevicePropertyStreamFormat, sizeof(formatDesc), &formatDesc);
- if( err == noErr ) result = 1;
- }
- }
- else result = 1;
- }
-
- return result;
-}
-
-#if 0
-static void PaOSX_DumpDeviceInfo( AudioDeviceID devID, Boolean isInput )
-{
- OSStatus err = noErr;
- UInt32 dataSize;
- UInt32 uidata32;
- Float32 fdata32;
- AudioValueRange audioRange;
-
- dataSize = sizeof( uidata32 );
- err = AudioDeviceGetProperty( devID, 0, isInput,
- kAudioDevicePropertyLatency, &dataSize, &uidata32 );
- if( err != noErr )
- {
- PRINT_ERR("Error reading kAudioDevicePropertyLatency", err);
- return;
- }
- PRINT(("kAudioDevicePropertyLatency = %d\n", (int)uidata32 ));
-
- dataSize = sizeof( fdata32 );
- err = AudioDeviceGetProperty( devID, 1, isInput,
- kAudioDevicePropertyVolumeScalar, &dataSize, &fdata32 );
- if( err != noErr )
- {
- PRINT_ERR("Error reading kAudioDevicePropertyVolumeScalar", err);
- return;
- }
- PRINT(("kAudioDevicePropertyVolumeScalar = %f\n", fdata32 ));
-
- dataSize = sizeof( uidata32 );
- err = AudioDeviceGetProperty( devID, 0, isInput,
- kAudioDevicePropertyBufferSize, &dataSize, &uidata32 );
- if( err != noErr )
- {
- PRINT_ERR("Error reading buffer size", err);
- return;
- }
- PRINT(("kAudioDevicePropertyBufferSize = %d bytes\n", (int)uidata32 ));
-
- dataSize = sizeof( audioRange );
- err = AudioDeviceGetProperty( devID, 0, isInput,
- kAudioDevicePropertyBufferSizeRange, &dataSize, &audioRange );
- if( err != noErr )
- {
- PRINT_ERR("Error reading buffer size range", err);
- return;
- }
- PRINT(("kAudioDevicePropertyBufferSizeRange = %g to %g bytes\n", audioRange.mMinimum, audioRange.mMaximum ));
-
- dataSize = sizeof( uidata32 );
- err = AudioDeviceGetProperty( devID, 0, isInput,
- kAudioDevicePropertyBufferFrameSize, &dataSize, &uidata32 );
- if( err != noErr )
- {
- PRINT_ERR("Error reading buffer size", err);
- return;
- }
- PRINT(("kAudioDevicePropertyBufferFrameSize = %d frames\n", (int)uidata32 ));
-
- dataSize = sizeof( audioRange );
- err = AudioDeviceGetProperty( devID, 0, isInput,
- kAudioDevicePropertyBufferFrameSizeRange, &dataSize, &audioRange );
- if( err != noErr )
- {
- PRINT_ERR("Error reading buffer size range", err);
- return;
- }
- PRINT(("kAudioDevicePropertyBufferFrameSizeRange = %g to %g frames\n", audioRange.mMinimum, audioRange.mMaximum ));
-
- return;
-}
-#endif
-
-/*******************************************************************/
-static OSStatus PAOSX_DevicePropertyListener (AudioDeviceID inDevice,
- UInt32 inChannel,
- Boolean isInput,
- AudioDevicePropertyID inPropertyID,
- void* inClientData)
-{
- PaHostSoundControl *pahsc;
- internalPortAudioStream *past;
- UInt32 dataSize;
- OSStatus err = noErr;
- AudioStreamBasicDescription userStreamFormat, hardwareStreamFormat;
- PaHostInOut *hostInOut;
- AudioStreamBasicDescription *destFormatPtr, *srcFormatPtr;
- AudioConverterRef oldConverter = NULL; // PLB 20031208 - Declare here for standard 'C'.
-
- past = (internalPortAudioStream *) inClientData;
- pahsc = (PaHostSoundControl *) past->past_DeviceData;
-
- DBUG(("PAOSX_DevicePropertyListener: called with propertyID = 0x%0X\n", (unsigned int) inPropertyID ));
-
- if(inPropertyID == kAudioDevicePropertyStreamFormat)
- {
- /* Get target device format */
- dataSize = sizeof(hardwareStreamFormat);
- err = AudioDeviceGetProperty(inDevice, 0, isInput,
- kAudioDevicePropertyStreamFormat, &dataSize, &hardwareStreamFormat);
- if( err != noErr )
- {
- PRINT_ERR("PAOSX_DevicePropertyListener: Could not get device format", err);
- sSavedHostError = err;
- goto error;
- }
-
- DBUG(("PAOSX_DevicePropertyListener: HW mChannelsPerFrame = %d\n", (int)hardwareStreamFormat.mChannelsPerFrame ));
-
- /* Set source user format. */
- userStreamFormat = hardwareStreamFormat;
- userStreamFormat.mSampleRate = past->past_SampleRate; // sample rate of the user synthesis code
- userStreamFormat.mChannelsPerFrame = (isInput) ? past->past_NumInputChannels : past->past_NumOutputChannels; // the number of channels in each frame
- DBUG(("PAOSX_DevicePropertyListener: User mChannelsPerFrame = %d\n", (int)userStreamFormat.mChannelsPerFrame ));
-
- userStreamFormat.mBytesPerFrame = userStreamFormat.mChannelsPerFrame * sizeof(float);
- userStreamFormat.mBytesPerPacket = userStreamFormat.mBytesPerFrame * userStreamFormat.mFramesPerPacket;
-
- /* Don't use AudioConverter for merging or splitting channels. */
- hardwareStreamFormat.mChannelsPerFrame = userStreamFormat.mChannelsPerFrame;
- hardwareStreamFormat.mBytesPerFrame = userStreamFormat.mBytesPerFrame;
- hardwareStreamFormat.mBytesPerPacket = userStreamFormat.mBytesPerPacket;
-
- if( isInput )
- {
- hostInOut = &pahsc->input;
- srcFormatPtr = &hardwareStreamFormat;
- destFormatPtr = &userStreamFormat;
- }
- else
- {
- hostInOut = &pahsc->output;
- srcFormatPtr = &userStreamFormat;
- destFormatPtr = &hardwareStreamFormat;
- }
- DBUG(("PAOSX_DevicePropertyListener: source rate = %f\n", srcFormatPtr->mSampleRate ));
- DBUG(("PAOSX_DevicePropertyListener: dest rate = %f\n", destFormatPtr->mSampleRate ));
-
- // Don't delete old converter until we create new one so we don't pull
- // the rug out from under other audio threads.
- oldConverter = hostInOut->converter;
-
- // Make converter to change sample rate.
- err = AudioConverterNew (
- srcFormatPtr,
- destFormatPtr,
- &hostInOut->converter );
- if( err != noErr )
- {
- PRINT_ERR("Could not create format converter", err);
- sSavedHostError = err;
- goto error;
- }
-
- if( oldConverter != NULL )
- {
- verify_noerr( AudioConverterDispose( oldConverter ) );
- }
- }
-
-error:
- pahsc->formatListenerCalled = true;
- return err;
-}
-
-/* Allocate FIFO between Device callback and Converter callback so that device can push data
-* and converter can pull data.
-*/
-static PaError PaOSX_CreateInputRingBuffer( internalPortAudioStream *past )
-{
- PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;
- OSStatus err = noErr;
- UInt32 dataSize;
- double sampleRateRatio;
- int32_t numBytes;
- UInt32 framesPerHostBuffer;
- UInt32 bytesForDevice;
- UInt32 bytesForUser;
- UInt32 bytesPerFrame;
- AudioStreamBasicDescription formatDesc;
-
- dataSize = sizeof(formatDesc);
- err = AudioDeviceGetProperty( pahsc->input.audioDeviceID, 0, IS_INPUT,
- kAudioDevicePropertyStreamFormat, &dataSize, &formatDesc);
- if( err != noErr )
- {
- PRINT_ERR("PaOSX_CreateInputRingBuffer: Could not get input format.\n", err);
- sSavedHostError = err;
- return paHostError;
- }
-
- // If device is delivering audio faster than being consumed then buffer must be bigger.
- sampleRateRatio = formatDesc.mSampleRate / past->past_SampleRate;
-
- // Get size of CoreAudio IO buffers.
- dataSize = sizeof(framesPerHostBuffer);
- err = AudioDeviceGetProperty( pahsc->input.audioDeviceID, 0, IS_INPUT,
- kAudioDevicePropertyBufferFrameSize, &dataSize,
- &framesPerHostBuffer);
- if( err != noErr )
- {
- PRINT_ERR("PaOSX_CreateInputRingBuffer: Could not get input buffer size.\n", err);
- sSavedHostError = err;
- return paHostError;
- }
-
- bytesPerFrame = past->past_NumInputChannels * sizeof(Float32);
-
- bytesForDevice = framesPerHostBuffer * bytesPerFrame * 2;
- bytesForUser = past->past_FramesPerUserBuffer * bytesPerFrame * 3 * sampleRateRatio;
-
- // Ring buffer should be large enough to consume audio input from device,
- // and to deliver a complete user buffer.
- numBytes = (bytesForDevice > bytesForUser) ? bytesForDevice : bytesForUser;
-
- numBytes = RoundUpToNextPowerOf2( numBytes );
-
- DBUG(("PaOSX_CreateInputRingBuffer: FIFO numBytes = %ld\n", numBytes));
- pahsc->ringBufferData = PaHost_AllocateFastMemory( numBytes );
- if( pahsc->ringBufferData == NULL )
- {
- return paInsufficientMemory;
- }
- RingBuffer_Init( &pahsc->ringBuffer, numBytes, pahsc->ringBufferData );
- // Make it look almost full at beginning. We must advance by an integral number of frames
- // so that the channels don't get scrambled when numChannels is not a power of 2.
- {
- int numZeroFrames = numBytes / bytesPerFrame;
- int numZeroBytes = numZeroFrames * bytesPerFrame;
- RingBuffer_AdvanceWriteIndex( &pahsc->ringBuffer, numZeroBytes );
- }
-
- return paNoError;
-}
-
-/******************************************************************
- * Try to set the I/O bufferSize of the device.
- * Scale the size by the ratio of the sample rates so that the converter will have
- * enough data to operate on.
- */
-static OSStatus PaOSX_SetDeviceBufferSize( AudioDeviceID devID, Boolean isInput, int framesPerUserBuffer, Float64 sampleRateRatio )
-{
- UInt32 dataSize;
- UInt32 ioBufferSize;
- int scaler;
-
- scaler = (int) sampleRateRatio;
- if( sampleRateRatio > (Float64) scaler ) scaler += 1;
- DBUG(("PaOSX_SetDeviceBufferSize: buffer size scaler = %d\n", scaler ));
- ioBufferSize = framesPerUserBuffer * scaler;
-
- // Limit buffer size to reasonable value.
- if( ioBufferSize < 128 ) ioBufferSize = 128;
-
- dataSize = sizeof(ioBufferSize);
- return AudioDeviceSetProperty( devID, 0, 0, isInput,
- kAudioDevicePropertyBufferFrameSize, dataSize,
- &ioBufferSize);
-}
-
-
-/*******************************************************************/
-static PaError PaOSX_OpenCommonDevice( internalPortAudioStream *past,
- PaHostInOut *inOut, Boolean isInput )
-{
- PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;
- PaError result = paNoError;
- OSStatus err = noErr;
- Float64 deviceRate;
-
-
- // The HW device format changes are asynchronous.
- // So we don't know when or if the PAOSX_DevicePropertyListener() will
- // get called. To be safe, call the listener now to forcibly create the converter.
- if( inOut->converter == NULL )
- {
- err = PAOSX_DevicePropertyListener (inOut->audioDeviceID,
- 0, isInput, kAudioDevicePropertyStreamFormat, past);
- if (err != kAudioHardwareNoError)
- {
- PRINT_ERR("PaOSX_OpenCommonDevice: PAOSX_DevicePropertyListener failed.\n", err);
- sSavedHostError = err;
- return paHostError;
- }
- }
-
- // Add listener for when format changed by other apps.
- DBUG(("PaOSX_OpenCommonDevice: call AudioDeviceAddPropertyListener()\n" ));
- err = AudioDeviceAddPropertyListener( inOut->audioDeviceID, 0, isInput,
- kAudioDevicePropertyStreamFormat,
- (AudioDevicePropertyListenerProc) PAOSX_DevicePropertyListener, past );
- if (err != noErr)
- {
- return -1; // FIXME
- }
-
- // Only change format if current HW format is different.
- // Don't bother to check result because we are going to use an AudioConverter anyway.
- pahsc->formatListenerCalled = false;
- result = PaOSX_SetFormat( inOut->audioDeviceID, isInput, past->past_SampleRate, inOut->numChannels );
- // Synchronize with device because format changes put some devices into unusable mode.
- if( result > 0 )
- {
- const int sleepDurMsec = 50;
- int spinCount = MIN_TIMEOUT_MSEC / sleepDurMsec;
- while( !pahsc->formatListenerCalled && (spinCount > 0) )
- {
- Pa_Sleep( sleepDurMsec ); // FIXME - use a semaphore or signal
- spinCount--;
- }
- if( !pahsc->formatListenerCalled )
- {
- PRINT(("PaOSX_OpenCommonDevice: timed out waiting for device format to settle.\n"));
- }
- result = 0;
- }
-
-#if SET_DEVICE_BUFFER_SIZE
- // Try to set the I/O bufferSize of the device.
- {
- Float64 ratio;
- deviceRate = PaOSX_GetDeviceSampleRate( inOut->audioDeviceID, isInput );
- if( deviceRate <= 0.0 ) deviceRate = past->past_SampleRate;
- ratio = deviceRate / past->past_SampleRate ;
- err = PaOSX_SetDeviceBufferSize( inOut->audioDeviceID, isInput,
- past->past_FramesPerUserBuffer, ratio );
- if( err != noErr )
- {
- DBUG(("PaOSX_OpenCommonDevice: Could not set I/O buffer size.\n"));
- }
- }
-#endif
-
- /* Allocate an input buffer because we need it between the user callback and the converter. */
- inOut->converterBuffer = PaHost_AllocateFastMemory( inOut->bytesPerUserNativeBuffer );
- if( inOut->converterBuffer == NULL )
- {
- return paInsufficientMemory;
- }
-
- return result;
-}
-
-/*******************************************************************/
-static PaError PaOSX_OpenInputDevice( internalPortAudioStream *past )
-{
- PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;
- const PaHostDeviceInfo *hostDeviceInfo;
- PaError result = paNoError;
-
- DBUG(("PaOSX_OpenInputDevice: -------------\n"));
-
- if( (past->past_InputDeviceID < LOWEST_INPUT_DEVID) ||
- (past->past_InputDeviceID > HIGHEST_INPUT_DEVID) )
- {
- return paInvalidDeviceId;
- }
- hostDeviceInfo = &sDeviceInfos[past->past_InputDeviceID];
-
- if( past->past_NumInputChannels > hostDeviceInfo->paInfo.maxInputChannels )
- {
- return paInvalidChannelCount; /* Too many channels! */
- }
- pahsc->input.numChannels = past->past_NumInputChannels;
-
- // setup PA conversion procedure
- result = PaConvert_SetupInput( past, paFloat32 );
-
- result = PaOSX_OpenCommonDevice( past, &pahsc->input, IS_INPUT );
- if( result != paNoError ) goto error;
-
- // Allocate a ring buffer so we can push in data from device, and pull through AudioConverter.
- result = PaOSX_CreateInputRingBuffer( past );
- if( result != paNoError ) goto error;
-
-error:
- return result;
-}
-
-/*******************************************************************/
-static PaError PaOSX_OpenOutputDevice( internalPortAudioStream *past )
-{
- PaHostSoundControl *pahsc;
- const PaHostDeviceInfo *hostDeviceInfo;
- PaError result = paNoError;
-
- DBUG(("PaOSX_OpenOutputDevice: -------------\n"));
- pahsc = (PaHostSoundControl *) past->past_DeviceData;
-
- // Validate DeviceID
- DBUG(("PaOSX_OpenOutputDevice: deviceID = 0x%x\n", past->past_OutputDeviceID));
- if( (past->past_OutputDeviceID < LOWEST_OUTPUT_DEVID) ||
- (past->past_OutputDeviceID > HIGHEST_OUTPUT_DEVID) )
- {
- return paInvalidDeviceId;
- }
- hostDeviceInfo = &sDeviceInfos[past->past_OutputDeviceID];
-
- // Validate number of channels.
- if( past->past_NumOutputChannels > hostDeviceInfo->paInfo.maxOutputChannels )
- {
- return paInvalidChannelCount; /* Too many channels! */
- }
- pahsc->output.numChannels = past->past_NumOutputChannels;
-
- // setup conversion procedure
- result = PaConvert_SetupOutput( past, paFloat32 );
- if( result != paNoError ) goto error;
-
- result = PaOSX_OpenCommonDevice( past, &pahsc->output, IS_OUTPUT );
- if( result != paNoError ) goto error;
-
-error:
- return result;
-}
-
-/*******************************************************************
-* Determine how many User Buffers we can put into our CoreAudio stream buffer.
-* Uses:
-* past->past_FramesPerUserBuffer, etc.
-* Sets:
-* past->past_NumUserBuffers
-* pahsc->input.bytesPerUserNativeBuffer
-* pahsc->output.bytesPerUserNativeBuffer
-*/
-static void PaOSX_CalcHostBufferSize( internalPortAudioStream *past )
-{
- PaHostSoundControl *pahsc = ( PaHostSoundControl *)past->past_DeviceData;
-
- // Determine number of user buffers based strictly on minimum reasonable buffer size.
- // We ignore the Pa_OpenStream numBuffer parameter because CoreAudio has a big
- // mix buffer and handles latency automatically.
- past->past_NumUserBuffers = Pa_GetMinNumBuffers( past->past_FramesPerUserBuffer, past->past_SampleRate );
-
- // calculate buffer sizes in bytes
- pahsc->input.bytesPerUserNativeBuffer = past->past_FramesPerUserBuffer *
- Pa_GetSampleSize(paFloat32) * past->past_NumInputChannels;
- pahsc->output.bytesPerUserNativeBuffer = past->past_FramesPerUserBuffer *
- Pa_GetSampleSize(paFloat32) * past->past_NumOutputChannels;
-
- DBUG(("PaOSX_CalcNumHostBuffers: past_NumUserBuffers = %ld\n", past->past_NumUserBuffers ));
- DBUG(("PaOSX_CalcNumHostBuffers: input.bytesPerUserNativeBuffer = %d\n", pahsc->input.bytesPerUserNativeBuffer ));
- DBUG(("PaOSX_CalcNumHostBuffers: output.bytesPerUserNativeBuffer = %d\n", pahsc->output.bytesPerUserNativeBuffer ));
-}
-
-/*****************************************************************************/
-/************** Internal Host API ********************************************/
-/*****************************************************************************/
-PaError PaHost_OpenStream( internalPortAudioStream *past )
-{
- PaError result = paNoError;
- PaHostSoundControl *pahsc;
- Boolean useInput;
- Boolean useOutput;
-
- assert( past->past_Magic == PA_MAGIC );
-
- /* Allocate and initialize host data. */
- pahsc = (PaHostSoundControl *) malloc(sizeof(PaHostSoundControl));
- if( pahsc == NULL )
- {
- result = paInsufficientMemory;
- goto error;
- }
- memset( pahsc, 0, sizeof(PaHostSoundControl) );
- past->past_DeviceData = (void *) pahsc;
- pahsc->primaryDeviceID = kAudioDeviceUnknown;
- pahsc->input.audioDeviceID = kAudioDeviceUnknown;
- pahsc->output.audioDeviceID = kAudioDeviceUnknown;
-
- PaOSX_CalcHostBufferSize( past );
-
- useOutput = (past->past_OutputDeviceID != paNoDevice) && (past->past_NumOutputChannels > 0);
- useInput = (past->past_InputDeviceID != paNoDevice) && (past->past_NumInputChannels > 0);
-
- // Set device IDs and determine IO Device mode.
- if( useOutput )
- {
- pahsc->output.audioDeviceID = sDeviceInfos[past->past_OutputDeviceID].audioDeviceID;
- pahsc->primaryDeviceID = pahsc->output.audioDeviceID;
- if( useInput )
- {
- pahsc->input.audioDeviceID = sDeviceInfos[past->past_InputDeviceID].audioDeviceID;
- pahsc->mode = ( pahsc->input.audioDeviceID != pahsc->primaryDeviceID ) ?
- PA_MODE_IO_TWO_DEVICES : PA_MODE_IO_ONE_DEVICE;
- }
- else
- {
- pahsc->mode = PA_MODE_OUTPUT_ONLY;
- }
- }
- else
- {
- /* Just input, not output. */
- pahsc->input.audioDeviceID = sDeviceInfos[past->past_InputDeviceID].audioDeviceID;
- pahsc->primaryDeviceID = pahsc->input.audioDeviceID;
- pahsc->mode = PA_MODE_INPUT_ONLY;
- }
-
- DBUG(("outputDeviceID = %ld\n", pahsc->output.audioDeviceID ));
- DBUG(("inputDeviceID = %ld\n", pahsc->input.audioDeviceID ));
- DBUG(("primaryDeviceID = %ld\n", pahsc->primaryDeviceID ));
-
- /* ------------------ OUTPUT */
- if( useOutput )
- {
- result = PaOSX_OpenOutputDevice( past );
- if( result < 0 ) goto error;
- }
-
- /* ------------------ INPUT */
- if( useInput )
- {
- result = PaOSX_OpenInputDevice( past );
- if( result < 0 ) goto error;
- }
-
-#if PA_ENABLE_LOAD_MEASUREMENT
- pahsc->inverseHostTicksPerBuffer = past->past_SampleRate /
- (AudioGetHostClockFrequency() * past->past_FramesPerUserBuffer);
- DBUG(("inverseHostTicksPerBuffer based on buffer size of %d frames.\n", past->past_FramesPerUserBuffer ));
-#else
- PRINT(("WARNING - Pa_GetCPULoad() mesaurement disabled in pa_mac_core.c.\n"));
-#endif
-
- return result;
-
-error:
- PaHost_CloseStream( past );
- return result;
-}
-
-/*************************************************************************/
-PaError PaHost_StartOutput( internalPortAudioStream *past )
-{
- return 0;
-}
-
-/*************************************************************************/
-PaError PaHost_StartInput( internalPortAudioStream *past )
-{
- return 0;
-}
-
-/*************************************************************************/
-PaError PaHost_StartEngine( internalPortAudioStream *past )
-{
- OSStatus err = noErr;
- PaError result = paNoError;
- PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;
-
- past->past_StopSoon = 0;
- past->past_StopNow = 0;
- past->past_IsActive = 1;
-
-/* If full duplex and using two separate devices then start input device. */
- if( pahsc->mode == PA_MODE_IO_TWO_DEVICES )
- {
- // Associate an IO proc with the device and pass a pointer to the audio data context
- err = AudioDeviceAddIOProc(pahsc->input.audioDeviceID, (AudioDeviceIOProc)PaOSX_CoreAudioInputCallback, past);
- if (err != noErr)
- {
- PRINT_ERR("PaHost_StartEngine: AudioDeviceAddIOProc secondary failed", err );
- goto error;
- }
-
- // start playing sound through the device
- err = AudioDeviceStart(pahsc->input.audioDeviceID, (AudioDeviceIOProc)PaOSX_CoreAudioInputCallback);
- if (err != noErr)
- {
- PRINT_ERR("PaHost_StartEngine: AudioDeviceStart secondary failed", err );
- PRINT(("The program may succeed if you run it again!\n"));
- goto error;
- }
- }
-
- // Associate an IO proc with the device and pass a pointer to the audio data context
- err = AudioDeviceAddIOProc(pahsc->primaryDeviceID, (AudioDeviceIOProc)PaOSX_CoreAudioIOCallback, past);
- if (err != noErr)
- {
- PRINT_ERR("PaHost_StartEngine: AudioDeviceAddIOProc primary failed", err );
- goto error;
- }
-
- // start playing sound through the device
- err = AudioDeviceStart(pahsc->primaryDeviceID, (AudioDeviceIOProc)PaOSX_CoreAudioIOCallback);
- if (err != noErr)
- {
- PRINT_ERR("PaHost_StartEngine: AudioDeviceStart primary failed", err );
- PRINT(("The program may succeed if you run it again!\n"));
- goto error;
- }
-
- return result;
-
-error:
- sSavedHostError = err;
- return paHostError;
-}
-
-/*************************************************************************/
-PaError PaHost_StopEngine( internalPortAudioStream *past, int abort )
-{
- OSStatus err = noErr;
- PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;
- if( pahsc == NULL ) return paNoError;
- (void) abort;
-
- /* Tell background thread to stop generating more data and to let current data play out. */
- past->past_StopSoon = 1;
- /* If aborting, tell background thread to stop NOW! */
- if( abort ) past->past_StopNow = 1;
- past->past_IsActive = 0;
-
-#if PA_TRACE_START_STOP
- AddTraceMessage( "PaHost_StopOutput: pahsc_HWaveOut ", (int) pahsc->pahsc_HWaveOut );
-#endif
-
- // FIXME - we should ask proc to stop instead of stopping abruptly
- err = AudioDeviceStop(pahsc->primaryDeviceID, (AudioDeviceIOProc)PaOSX_CoreAudioIOCallback);
- if (err != noErr)
- {
- goto error;
- }
-
- err = AudioDeviceRemoveIOProc(pahsc->primaryDeviceID, (AudioDeviceIOProc)PaOSX_CoreAudioIOCallback);
- if (err != noErr) goto error;
-
-/* If full duplex and using two separate devices then stop second input device. */
- if( pahsc->mode == PA_MODE_IO_TWO_DEVICES )
- {
- err = AudioDeviceStop(pahsc->input.audioDeviceID, (AudioDeviceIOProc)PaOSX_CoreAudioInputCallback);
- if (err != noErr) goto error;
- err = AudioDeviceRemoveIOProc(pahsc->input.audioDeviceID, (AudioDeviceIOProc)PaOSX_CoreAudioInputCallback);
- if (err != noErr) goto error;
- }
-
- return paNoError;
-
-error:
- sSavedHostError = err;
- return paHostError;
-}
-
-/*************************************************************************/
-PaError PaHost_StopInput( internalPortAudioStream *past, int abort )
-{
- return paNoError;
-}
-
-/*************************************************************************/
-PaError PaHost_StopOutput( internalPortAudioStream *past, int abort )
-{
- return paNoError;
-}
-
-/*******************************************************************/
-PaError PaHost_CloseStream( internalPortAudioStream *past )
-{
- PaHostSoundControl *pahsc;
-
- if( past == NULL ) return paBadStreamPtr;
- pahsc = (PaHostSoundControl *) past->past_DeviceData;
- if( pahsc == NULL ) return paNoError;
-
- //PaOSX_DumpDeviceInfo( sDeviceInfos[past->past_OutputDeviceID].audioDeviceID, IS_OUTPUT );
-
-#if PA_TRACE_START_STOP
- AddTraceMessage( "PaHost_CloseStream: pahsc_HWaveOut ", (int) pahsc->pahsc_HWaveOut );
-#endif
- // Stop Listener callbacks ASAP before dismantling stream.
- if( PA_USING_INPUT )
- {
- AudioDeviceRemovePropertyListener( pahsc->input.audioDeviceID, 0, IS_INPUT,
- kAudioDevicePropertyStreamFormat,
- (AudioDevicePropertyListenerProc) PAOSX_DevicePropertyListener );
- }
-
- if( PA_USING_OUTPUT )
- {
- AudioDeviceRemovePropertyListener( pahsc->output.audioDeviceID, 0, IS_OUTPUT,
- kAudioDevicePropertyStreamFormat,
- (AudioDevicePropertyListenerProc) PAOSX_DevicePropertyListener );
- }
-
- if( pahsc->output.converterBuffer != NULL )
- {
- PaHost_FreeFastMemory( pahsc->output.converterBuffer, pahsc->output.bytesPerUserNativeBuffer );
- }
- if( pahsc->input.converterBuffer != NULL )
- {
- PaHost_FreeFastMemory( pahsc->input.converterBuffer, pahsc->input.bytesPerUserNativeBuffer );
- }
- if( pahsc->ringBufferData != NULL )
- {
- PaHost_FreeFastMemory( pahsc->ringBufferData, pahsc->ringBuffer.bufferSize );
- }
- if( pahsc->output.converter != NULL )
- {
- verify_noerr(AudioConverterDispose (pahsc->output.converter));
- }
- if( pahsc->input.converter != NULL )
- {
- verify_noerr(AudioConverterDispose (pahsc->input.converter));
- }
- if ( pahsc->input.streamInterleavingBuffer != NULL )
- {
- PaHost_FreeFastMemory( pahsc->input.streamInterleavingBuffer, pahsc->input.streamInterleavingBufferLen );
- }
- if ( pahsc->output.streamInterleavingBuffer != NULL )
- {
- PaHost_FreeFastMemory( pahsc->output.streamInterleavingBuffer, pahsc->output.streamInterleavingBufferLen );
- }
-
- free( pahsc );
- past->past_DeviceData = NULL;
-
- return paNoError;
-}
-
-/**********************************************************************
-** Initialize Host dependant part of API.
-*/
-PaError PaHost_Init( void )
-{
- return PaOSX_MaybeQueryDevices();
-}
-
-/*************************************************************************
-** Cleanup device info.
-*/
-PaError PaHost_Term( void )
-{
- int i;
-
- if( sDeviceInfos != NULL )
- {
- for( i=0; i<sNumPaDevices; i++ )
- {
- if( sDeviceInfos[i].paInfo.name != NULL )
- {
- free( (char*)sDeviceInfos[i].paInfo.name );
- }
- }
- free( sDeviceInfos );
- sDeviceInfos = NULL;
- }
-
- sNumPaDevices = 0;
- return paNoError;
-}
-
-/*************************************************************************
- * Allocate memory that can be accessed in real-time.
- * This may need to be held in physical memory so that it is not
- * paged to virtual memory.
- * This call MUST be balanced with a call to PaHost_FreeFastMemory().
- */
-void *PaHost_AllocateFastMemory( int32_t numBytes )
-{
- void *addr = malloc( numBytes ); /* FIXME - do we need physical memory, not virtual memory? */
- if( addr != NULL ) memset( addr, 0, numBytes );
- return addr;
-}
-
-/*************************************************************************
- * Free memory that could be accessed in real-time.
- * This call MUST be balanced with a call to PaHost_AllocateFastMemory().
- */
-void PaHost_FreeFastMemory( void *addr, int32_t numBytes )
-{
- if( addr != NULL ) free( addr );
-}
-
-
-/***********************************************************************/
-PaError PaHost_StreamActive( internalPortAudioStream *past )
-{
- PaHostSoundControl *pahsc;
- if( past == NULL ) return paBadStreamPtr;
- pahsc = (PaHostSoundControl *) past->past_DeviceData;
- if( pahsc == NULL ) return paInternalError;
- return (PaError) past->past_IsActive;
-}
-
-/*****************************************************************************/
-/************** External User API ********************************************/
-/*****************************************************************************/
-
-/**********************************************************************
-** Query devices and use result.
-*/
-PaDeviceID Pa_GetDefaultInputDeviceID( void )
-{
- PaError result = PaOSX_MaybeQueryDevices();
- if( result < 0 ) return result;
- return sDefaultInputDeviceID;
-}
-
-PaDeviceID Pa_GetDefaultOutputDeviceID( void )
-{
- PaError result = PaOSX_MaybeQueryDevices();
- if( result < 0 ) return result;
- return sDefaultOutputDeviceID;
-}
-
-
-/*************************************************************************
-** Determine minimum number of buffers required for this host based
-** on minimum latency. Because CoreAudio manages latency, this just selects
-** a reasonably small number of buffers.
-*/
-int Pa_GetMinNumBuffers( int framesPerBuffer, double framesPerSecond )
-{
- int minBuffers;
- double denominator;
- int minLatencyMsec = PA_MIN_LATENCY_MSEC;
- denominator = 1000.0 * framesPerBuffer;
- minBuffers = (int) (((minLatencyMsec * framesPerSecond) + denominator - 1) / denominator );
- if( minBuffers < 1 ) minBuffers = 1;
- return minBuffers;
-}
-
-/*************************************************************************/
-void Pa_Sleep( int32_t msec )
-{
- usleep( msec * 1000 );
-}
-
-/*************************************************************************/
-PaTimestamp Pa_StreamTime( PortAudioStream *stream )
-{
- AudioTimeStamp timeStamp;
- PaTimestamp streamTime;
- PaHostSoundControl *pahsc;
- internalPortAudioStream *past = (internalPortAudioStream *) stream;
- if( past == NULL ) return paBadStreamPtr;
- pahsc = (PaHostSoundControl *) past->past_DeviceData;
-
- AudioDeviceGetCurrentTime(pahsc->primaryDeviceID, &timeStamp);
-
- streamTime = ( timeStamp.mFlags & kAudioTimeStampSampleTimeValid) ?
- timeStamp.mSampleTime : past->past_FrameCount;
-
- return streamTime;
-}
-
-/************************************************************************************/
-int32_t Pa_GetHostError()
-{
- return sSavedHostError;
-}
-
-/*************************************************************************/
-int Pa_CountDevices()
-{
- if( sNumPaDevices <= 0 ) Pa_Initialize();
- return sNumPaDevices;
-}
-
-/*************************************************************************
-** PaDeviceInfo structures have already been created
-** so just return the pointer.
-**
-*/
-const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceID id )
-{
- if( id < 0 || id >= sNumPaDevices )
- return NULL;
-
- return &sDeviceInfos[id].paInfo;
-}
-
-
-
-#endif
diff --git a/lib/portaudio/pa_trace.c b/lib/portaudio/pa_trace.c
deleted file mode 100644
index 08e68f5..0000000
--- a/lib/portaudio/pa_trace.c
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * $Id$
- * Portable Audio I/O Library Trace Facility
- * Store trace information in real-time for later printing.
- *
- * Based on the Open Source API proposed by Ross Bencina
- * Copyright (c) 1999-2000 Phil Burk
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files
- * (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * Any person wishing to distribute modifications to the Software is
- * requested to send the modifications to the original developer so that
- * they can be incorporated into the canonical version.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "pa_trace.h"
-
-#if TRACE_REALTIME_EVENTS
-
-static char *traceTextArray[MAX_TRACE_RECORDS];
-static int traceIntArray[MAX_TRACE_RECORDS];
-static int traceIndex = 0;
-static int traceBlock = 0;
-
-/*********************************************************************/
-void ResetTraceMessages()
-{
- traceIndex = 0;
-}
-
-/*********************************************************************/
-void DumpTraceMessages()
-{
- int i;
- int numDump = (traceIndex < MAX_TRACE_RECORDS) ? traceIndex : MAX_TRACE_RECORDS;
-
- printf("DumpTraceMessages: traceIndex = %d\n", traceIndex );
- for( i=0; i<numDump; i++ )
- {
- printf("%3d: %s = 0x%08X\n",
- i, traceTextArray[i], traceIntArray[i] );
- }
- ResetTraceMessages();
- fflush(stdout);
-}
-
-/*********************************************************************/
-void AddTraceMessage( char *msg, int data )
-{
- if( (traceIndex == MAX_TRACE_RECORDS) && (traceBlock == 0) )
- {
- traceBlock = 1;
- /* DumpTraceMessages(); */
- }
- else if( traceIndex < MAX_TRACE_RECORDS )
- {
- traceTextArray[traceIndex] = msg;
- traceIntArray[traceIndex] = data;
- traceIndex++;
- }
-}
-
-#endif
diff --git a/lib/portaudio/pa_trace.h b/lib/portaudio/pa_trace.h
deleted file mode 100644
index e3fa8ca..0000000
--- a/lib/portaudio/pa_trace.h
+++ /dev/null
@@ -1,67 +0,0 @@
-#ifndef PA_TRACE_H
-#define PA_TRACE_H
-/*
- * $Id$
- * Portable Audio I/O Library Trace Facility
- * Store trace information in real-time for later printing.
- *
- * Based on the Open Source API proposed by Ross Bencina
- * Copyright (c) 1999-2000 Phil Burk
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files
- * (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * Any person wishing to distribute modifications to the Software is
- * requested to send the modifications to the original developer so that
- * they can be incorporated into the canonical version.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-
-#define TRACE_REALTIME_EVENTS (0) /* Keep log of various real-time events. */
-#define MAX_TRACE_RECORDS (2048)
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-
- /************************************************************************************/
- /****************** Prototypes ******************************************************/
- /************************************************************************************/
-
-#if TRACE_REALTIME_EVENTS
-
- void DumpTraceMessages();
- void ResetTraceMessages();
- void AddTraceMessage( char *msg, int data );
-
-#else
-
-#define AddTraceMessage(msg,data) /* noop */
-#define ResetTraceMessages() /* noop */
-#define DumpTraceMessages() /* noop */
-
-#endif
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* PA_TRACE_H */
diff --git a/lib/portaudio/pa_unix.c b/lib/portaudio/pa_unix.c
deleted file mode 100644
index 69dfeab..0000000
--- a/lib/portaudio/pa_unix.c
+++ /dev/null
@@ -1,1127 +0,0 @@
-/*
- * PortAudio Portable Real-Time Audio Library
- * Latest Version at: http://www.portaudio.com
- * Linux OSS Implementation by douglas repetto and Phil Burk
- *
- * Copyright (c) 1999-2000 Phil Burk
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files
- * (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * Any person wishing to distribute modifications to the Software is
- * requested to send the modifications to the original developer so that
- * they can be incorporated into the canonical version.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- */
-
-/*
-Modification History
- 1/2001 - Phil Burk - initial hack for Linux
- 2/2001 - Douglas Repetto - many improvements, initial query support
- 4/2/2001 - Phil - stop/abort thread control, separate in/out native buffers
- 5/28/2001 - Phil - use pthread_create() instead of clone(). Thanks Stephen Brandon!
- use pthread_join() after thread shutdown.
- 5/29/2001 - Phil - query for multiple devices, multiple formats,
- input mode and input+output mode working,
- Pa_GetCPULoad() implemented.
- PLB20010817 - Phil & Janos Haber - don't halt if test of sample rate fails.
- SB20010904 - Stephen Brandon - mods needed for GNUSTEP and SndKit
- JH20010905 - Janos Haber - FreeBSD mods
- 2001-09-22 - Heiko - (i.e. Heiko Purnhagen <purnhage@tnt.uni-hannover.de> ;-)
- added 24k and 16k to ratesToTry[]
- fixed Pa_GetInternalDevice()
- changed DEVICE_NAME_BASE from /dev/audio to /dev/dsp
- handled SNDCTL_DSP_SPEED in Pq_QueryDevice() more graceful
- fixed Pa_StreamTime() for paqa_errs.c
- fixed numCannel=2 oddity and error handling in Pa_SetupDeviceFormat()
- grep also for HP20010922 ...
- PLB20010924 - Phil - merged Heiko's changes
- removed sNumDevices and potential related bugs,
- use getenv("PA_MIN_LATENCY_MSEC") to set desired latency,
- simplify CPU Load calculation by comparing real-time to framesPerBuffer,
- always close device when querying even if error occurs,
- PLB20010927 - Phil - Improved negotiation for numChannels.
- SG20011005 - Stewart Greenhill - set numChannels back to reasonable value after query.
- DH20010115 - David Herring - fixed uninitialized handle.
-
- DM20020218 - Dominic Mazzoni - Try to open in nonblocking mode first, in case
- the device is already open. New implementation of
- Pa_StreamTime that uses SNDCTL_DSP_GETOPTR but
- uses our own counter to avoid wraparound.
- PLB20020222 - Phil Burk - Added WatchDog proc if audio running at high priority.
- Check error return from read() and write().
- Check CPU endianness instead of assuming Little Endian.
- 20020621 - pa_unix_oss.c split into pa_unix.c, pa_unix.h, pa_unix_oss.c by
- Augustus Saunders. Return values from usleep() ignored by Sam Bayer
- because not cross-platform compatible (at least until we get configure
- going). Pa_SetupDeviceFormat split into input and output sides to
- reflect capabilities of Solaris.
-
- 20030206 - Martin Rohrbach - various mods for Solaris
-
- 20030410 - Bjorn Dittmer-Roche - fixed numerous problems associated with pthread_t
-
- 20030630 - Thomas Richter - eliminated unused variable warnings.
-
-TODO
-O- put semaphore lock around shared data?
-O- handle native formats better
-O- handle stereo-only device better ???
-O- what if input and output of a device capabilities differ (e.g. es1371) ???
-*/
-
-#include <config.h>
-#ifdef HAVE_UNIX
-
-#include "pa_unix.h"
-
-typedef void *(*pthread_function_t)(void *);
-
-/************************************************* Shared Data ********/
-/* FIXME - put Mutex around this shared data. */
-static internalPortAudioDevice *sDeviceList = NULL;
-static int sDefaultInputDeviceID = paNoDevice;
-static int sDefaultOutputDeviceID = paNoDevice;
-static int sPaHostError = 0;
-
-/********************************* BEGIN CPU UTILIZATION MEASUREMENT ****/
-static void Pa_StartUsageCalculation( internalPortAudioStream *past )
-{
- PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;
- if( pahsc == NULL ) return;
- /* Query system timer for usage analysis and to prevent overuse of CPU. */
- gettimeofday( &pahsc->pahsc_EntryTime, NULL );
-}
-
-static int32_t SubtractTime_AminusB( struct timeval *timeA, struct timeval *timeB )
-{
- int32_t secs = timeA->tv_sec - timeB->tv_sec;
- int32_t usecs = secs * 1000000;
- usecs += (timeA->tv_usec - timeB->tv_usec);
- return usecs;
-}
-
-/******************************************************************************
-** Measure fractional CPU load based on real-time it took to calculate
-** buffers worth of output.
-*/
-static void Pa_EndUsageCalculation( internalPortAudioStream *past )
-{
- struct timeval currentTime;
- int32_t usecsElapsed;
- double newUsage;
-
-#define LOWPASS_COEFFICIENT_0 (0.95)
-#define LOWPASS_COEFFICIENT_1 (0.99999 - LOWPASS_COEFFICIENT_0)
-
- PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;
- if( pahsc == NULL ) return;
-
- if( gettimeofday( &currentTime, NULL ) == 0 )
- {
- usecsElapsed = SubtractTime_AminusB( &currentTime, &pahsc->pahsc_EntryTime );
- /* Use inverse because it is faster than the divide. */
- newUsage = usecsElapsed * pahsc->pahsc_InverseMicrosPerBuffer;
-
- past->past_Usage = (LOWPASS_COEFFICIENT_0 * past->past_Usage) +
- (LOWPASS_COEFFICIENT_1 * newUsage);
-
- }
-}
-/****************************************** END CPU UTILIZATION *******/
-
-/*********************************************************************
- * Determines the number of available devices by trying to open
- * each "/dev/dsp#" or "/dsp/audio#" in order until it fails.
- * Add each working device to a singly linked list of devices.
- */
-PaError Pa_QueryDevices( void )
-{
- internalPortAudioDevice *pad, *lastPad;
- int go = 1;
- int numDevices = 0;
- PaError testResult;
- PaError result = paNoError;
- char *envdev;
-
- sDefaultInputDeviceID = paNoDevice;
- sDefaultOutputDeviceID = paNoDevice;
-
- lastPad = NULL;
-
- while( go )
- {
- /* Allocate structure to hold device info. */
- pad = (internalPortAudioDevice *)
- PaHost_AllocateFastMemory( sizeof(internalPortAudioDevice) );
- if( pad == NULL ) return paInsufficientMemory;
- memset( pad, 0, sizeof(internalPortAudioDevice) );
-
- /* Build name for device. */
- if( numDevices == 0 )
- {
- sprintf( pad->pad_DeviceName, DEVICE_NAME_BASE);
- }
- else
- {
- sprintf( pad->pad_DeviceName, DEVICE_NAME_BASE "%d", numDevices );
- }
-
- DBUG(("Try device %s\n", pad->pad_DeviceName ));
- testResult = Pa_QueryDevice( pad->pad_DeviceName, pad );
- DBUG(("Pa_QueryDevice returned %d\n", testResult ));
- if( testResult != paNoError )
- {
- if( lastPad == NULL )
- {
- result = testResult; /* No good devices! */
- }
- go = 0;
- PaHost_FreeFastMemory( pad, sizeof(internalPortAudioDevice) );
- }
- else
- {
- numDevices += 1;
- /* Add to linked list of devices. */
- if( lastPad )
- {
- lastPad->pad_Next = pad;
- }
- else
- {
- sDeviceList = pad; /* First element in linked list. */
- }
- lastPad = pad;
- }
- }
-
- /* I'm sitting at a SunRay1 and I neither have /dev/audio# nor /dev/dsp#.
- Instead, the correct audio device is stored in the environment variable
- AUDIODEV and/or UTAUDIODEV, so check these devices as well if we haven't
- checked them yet above - MR */
-
- DBUG(("Checking for AUDIODEV and UTAUDIODEV\n"));
- envdev = getenv("AUDIODEV");
- if (envdev != NULL && !strstr(envdev, DEVICE_NAME_BASE)) {
- result = paNoError;
-
- /* Allocate structure to hold device info. */
- pad = (internalPortAudioDevice *)
- PaHost_AllocateFastMemory( sizeof(internalPortAudioDevice) );
- if( pad == NULL ) return paInsufficientMemory;
- memset( pad, 0, sizeof(internalPortAudioDevice) );
-
- /* Build name for device. */
- strcpy(pad->pad_DeviceName, envdev);
-
- DBUG(("Try device %s\n", pad->pad_DeviceName ));
- testResult = Pa_QueryDevice( pad->pad_DeviceName, pad );
- DBUG(("Pa_QueryDevice returned %d\n", testResult ));
- if( testResult != paNoError )
- {
- if( lastPad == NULL )
- {
- result = testResult; /* No good devices! */
- }
- PaHost_FreeFastMemory( pad, sizeof(internalPortAudioDevice) );
- }
- else
- {
- numDevices += 1;
- /* Add to linked list of devices. */
- if( lastPad )
- {
- lastPad->pad_Next = pad;
- }
- else
- {
- sDeviceList = pad; /* First element in linked list. */
- }
- lastPad = pad;
- }
- }
-
- envdev = getenv("UTAUDIODEV");
- if (envdev != NULL && !strstr(envdev, DEVICE_NAME_BASE) && getenv("AUDIODEV") != NULL && strcmp(envdev, getenv("AUDIODEV"))) {
- result = paNoError;
-
- /* Allocate structure to hold device info. */
- pad = (internalPortAudioDevice *)
- PaHost_AllocateFastMemory( sizeof(internalPortAudioDevice) );
- if( pad == NULL ) return paInsufficientMemory;
- memset( pad, 0, sizeof(internalPortAudioDevice) );
-
- /* Build name for device. */
- strcpy(pad->pad_DeviceName, envdev);
-
- DBUG(("Try device %s\n", pad->pad_DeviceName ));
- testResult = Pa_QueryDevice( pad->pad_DeviceName, pad );
- DBUG(("Pa_QueryDevice returned %d\n", testResult ));
- if( testResult != paNoError )
- {
- if( lastPad == NULL )
- {
- result = testResult; /* No good devices! */
- }
- PaHost_FreeFastMemory( pad, sizeof(internalPortAudioDevice) );
- }
- else
- {
- numDevices += 1;
- /* Add to linked list of devices. */
- if( lastPad )
- {
- lastPad->pad_Next = pad;
- }
- else
- {
- sDeviceList = pad; /* First element in linked list. */
- }
- lastPad = pad;
- }
- }
-
- return result;
-}
-
-/*************************************************************************/
-int Pa_CountDevices()
-{
- int numDevices = 0;
- internalPortAudioDevice *pad;
-
- if( sDeviceList == NULL ) Pa_Initialize();
- /* Count devices in list. */
- pad = sDeviceList;
- while( pad != NULL )
- {
- pad = pad->pad_Next;
- numDevices++;
- }
-
- return numDevices;
-}
-
-/*************************************************************************/
-internalPortAudioDevice *Pa_GetInternalDevice( PaDeviceID id )
-{
- internalPortAudioDevice *pad;
- if( (id < 0) || ( id >= Pa_CountDevices()) ) return NULL;
- pad = sDeviceList;
- while( id > 0 )
- {
- pad = pad->pad_Next;
- id--;
- }
- return pad;
-}
-
-/*************************************************************************/
-const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceID id )
-{
- internalPortAudioDevice *pad;
- if( (id < 0) || ( id >= Pa_CountDevices()) ) return NULL;
- pad = Pa_GetInternalDevice( id );
- return &pad->pad_Info ;
-}
-
-static PaError Pa_MaybeQueryDevices( void )
-{
- if( sDeviceList == NULL )
- {
- return Pa_QueryDevices();
- }
- return 0;
-}
-
-PaDeviceID Pa_GetDefaultInputDeviceID( void )
-{
- /* return paNoDevice; */
- return 0;
-}
-
-PaDeviceID Pa_GetDefaultOutputDeviceID( void )
-{
- return 0;
-}
-
-/**********************************************************************
-** Make sure that we have queried the device capabilities.
-*/
-
-PaError PaHost_Init( void )
-{
- return Pa_MaybeQueryDevices();
-}
-
-/*******************************************************************************************
- * The ol' Canary in a Coal Mine trick.
- * Just update the time periodically.
- * Runs at low priority so if audio thread runs wild, this thread will get starved
- * and the watchdog will detect it.
- */
-
-#define SCHEDULER_POLICY SCHED_RR
-#define WATCHDOG_MAX_SECONDS (3)
-#define WATCHDOG_INTERVAL_USEC (1000000)
-
-static int PaHost_CanaryProc( PaHostSoundControl *pahsc )
-{
- int result = 0;
-
-#ifdef GNUSTEP
- GSRegisterCurrentThread(); /* SB20010904 */
-#endif
-
- while( pahsc->pahsc_CanaryRun) {
- usleep( WATCHDOG_INTERVAL_USEC );
- gettimeofday( &pahsc->pahsc_CanaryTime, NULL );
- }
-
- DBUG(("PaHost_CanaryProc: exiting.\n"));
-
-#ifdef GNUSTEP
- GSUnregisterCurrentThread(); /* SB20010904 */
-#endif
-
- return result;
-}
-
-/*******************************************************************************************
- * Monitor audio thread and lower its it if it hogs the CPU.
- * To prevent getting killed, the audio thread must update a
- * variable with a timer value.
- * If the value is not recent enough, then the
- * thread will get killed.
- */
-
-static PaError PaHost_WatchDogProc( PaHostSoundControl *pahsc )
-{
- struct sched_param schp = { 0 };
- int maxPri;
-
-#ifdef GNUSTEP
- GSRegisterCurrentThread(); /* SB20010904 */
-#endif
-
-/* Run at a priority level above audio thread so we can still run if it hangs. */
-/* Rise more than 1 because of rumored off-by-one scheduler bugs. */
- schp.sched_priority = pahsc->pahsc_AudioPriority + 4;
- maxPri = sched_get_priority_max(SCHEDULER_POLICY);
- if( schp.sched_priority > maxPri ) schp.sched_priority = maxPri;
-
- if (sched_setscheduler(0, SCHEDULER_POLICY, &schp) != 0)
- {
- ERR_RPT(("PaHost_WatchDogProc: cannot set watch dog priority!\n"));
- goto killAudio;
- }
-
- /* Compare watchdog time with audio and canary thread times. */
- /* Sleep for a while or until thread cancelled. */
- while( pahsc->pahsc_WatchDogRun )
- {
-
- int delta;
- struct timeval currentTime;
-
- usleep( WATCHDOG_INTERVAL_USEC );
- gettimeofday( &currentTime, NULL );
-
- /* If audio thread is not advancing, then it must be hung so kill it. */
- delta = currentTime.tv_sec - pahsc->pahsc_EntryTime.tv_sec;
- DBUG(("PaHost_WatchDogProc: audio delta = %d\n", delta ));
- if( delta > WATCHDOG_MAX_SECONDS )
- {
- goto killAudio;
- }
-
- /* If canary died, then lower audio priority and halt canary. */
- delta = currentTime.tv_sec - pahsc->pahsc_CanaryTime.tv_sec;
- if( delta > WATCHDOG_MAX_SECONDS )
- {
- ERR_RPT(("PaHost_WatchDogProc: canary died!\n"));
- goto lowerAudio;
- }
- }
-
- DBUG(("PaHost_WatchDogProc: exiting.\n"));
-#ifdef GNUSTEP
- GSUnregisterCurrentThread(); /* SB20010904 */
-#endif
- return 0;
-
-lowerAudio:
- {
- struct sched_param schat = { 0 };
- if( sched_setscheduler(pahsc->pahsc_AudioThreadPID, SCHED_OTHER, &schat) != 0)
- {
- ERR_RPT(("PaHost_WatchDogProc: failed to lower audio priority. errno = %d\n", errno ));
- /* Fall through into killing audio thread. */
- }
- else
- {
- ERR_RPT(("PaHost_WatchDogProc: lowered audio priority to prevent hogging of CPU.\n"));
- goto cleanup;
- }
- }
-
-killAudio:
- ERR_RPT(("PaHost_WatchDogProc: killing hung audio thread!\n"));
- pthread_kill( pahsc->pahsc_AudioThread, SIGKILL );
-
-cleanup:
- pahsc->pahsc_CanaryRun = 0;
- DBUG(("PaHost_WatchDogProc: cancel Canary\n"));
- pthread_cancel( pahsc->pahsc_CanaryThread );
- DBUG(("PaHost_WatchDogProc: join Canary\n"));
- pthread_join( pahsc->pahsc_CanaryThread, NULL );
- DBUG(("PaHost_WatchDogProc: forget Canary\n"));
- pahsc->pahsc_IsCanaryThreadValid = 0;
-
-#ifdef GNUSTEP
- GSUnregisterCurrentThread(); /* SB20010904 */
-#endif
- return 0;
-}
-
-/*******************************************************************************************/
-static void PaHost_StopWatchDog( PaHostSoundControl *pahsc )
-{
-/* Cancel WatchDog thread if there is one. */
- if( pahsc->pahsc_IsWatchDogThreadValid )
- {
- pahsc->pahsc_WatchDogRun = 0;
- DBUG(("PaHost_StopWatchDog: cancel WatchDog\n"));
- pthread_cancel( pahsc->pahsc_WatchDogThread );
- pthread_join( pahsc->pahsc_WatchDogThread, NULL );
- pahsc->pahsc_IsWatchDogThreadValid = 0;
- }
-/* Cancel Canary thread if there is one. */
- if( pahsc->pahsc_IsCanaryThreadValid )
- {
- pahsc->pahsc_CanaryRun = 0;
- DBUG(("PaHost_StopWatchDog: cancel Canary\n"));
- pthread_cancel( pahsc->pahsc_CanaryThread );
- DBUG(("PaHost_StopWatchDog: join Canary\n"));
- pthread_join( pahsc->pahsc_CanaryThread, NULL );
- pahsc->pahsc_IsCanaryThreadValid = 0;
- }
-}
-
-/*******************************************************************************************/
-static PaError PaHost_StartWatchDog( PaHostSoundControl *pahsc )
-{
- int hres;
- PaError result = 0;
-
- /* The watch dog watches for these timer updates */
- gettimeofday( &pahsc->pahsc_EntryTime, NULL );
- gettimeofday( &pahsc->pahsc_CanaryTime, NULL );
-
- /* Launch a canary thread to detect priority abuse. */
- pahsc->pahsc_CanaryRun = 1;
- hres = pthread_create(&(pahsc->pahsc_CanaryThread),
- NULL /*pthread_attr_t * attr*/,
- (pthread_function_t)PaHost_CanaryProc, pahsc);
- if( hres != 0 )
- {
- pahsc->pahsc_IsCanaryThreadValid = 0;
- result = paHostError;
- sPaHostError = hres;
- goto error;
- }
- pahsc->pahsc_IsCanaryThreadValid = 1;
-
- /* Launch a watchdog thread to prevent runaway audio thread. */
- pahsc->pahsc_WatchDogRun = 1;
- hres = pthread_create(&(pahsc->pahsc_WatchDogThread),
- NULL /*pthread_attr_t * attr*/,
- (pthread_function_t)PaHost_WatchDogProc, pahsc);
- if( hres != 0 )
- {
- pahsc->pahsc_IsWatchDogThreadValid = 0;
- result = paHostError;
- sPaHostError = hres;
- goto error;
- }
- pahsc->pahsc_IsWatchDogThreadValid = 1;
- return result;
-
-error:
- PaHost_StopWatchDog( pahsc );
- return result;
-}
-
-/*******************************************************************************************
- * Bump priority of audio thread if running with superuser priveledges.
- * if priority bumped then launch a watchdog.
- */
-static PaError PaHost_BoostPriority( internalPortAudioStream *past )
-{
- PaHostSoundControl *pahsc;
- PaError result = paNoError;
- struct sched_param schp = { 0 };
-
- pahsc = (PaHostSoundControl *) past->past_DeviceData;
- if( pahsc == NULL ) return paInternalError;
-
- pahsc->pahsc_AudioThreadPID = getpid();
- DBUG(("PaHost_BoostPriority: audio PID = %d\n", pahsc->pahsc_AudioThreadPID ));
-
- /* Choose a priority in the middle of the range. */
- pahsc->pahsc_AudioPriority = (sched_get_priority_max(SCHEDULER_POLICY) -
- sched_get_priority_min(SCHEDULER_POLICY)) / 2;
- schp.sched_priority = pahsc->pahsc_AudioPriority;
-
- if (sched_setscheduler(0, SCHEDULER_POLICY, &schp) != 0)
- {
- DBUG(("PortAudio: only superuser can use real-time priority.\n"));
- }
- else
- {
- DBUG(("PortAudio: audio callback priority set to level %d!\n", schp.sched_priority));
- /* We are running at high priority so we should have a watchdog in case audio goes wild. */
- result = PaHost_StartWatchDog( pahsc );
- }
-
- return result;
-}
-
-/*******************************************************************************************/
-static PaError Pa_AudioThreadProc( internalPortAudioStream *past )
-{
- PaError result;
- PaHostSoundControl *pahsc;
- ssize_t bytes_read, bytes_written;
-
- pahsc = (PaHostSoundControl *) past->past_DeviceData;
- if( pahsc == NULL ) return paInternalError;
-
-#ifdef GNUSTEP
- GSRegisterCurrentThread(); /* SB20010904 */
-#endif
-
- result = PaHost_BoostPriority( past );
- if( result < 0 ) goto error;
-
- past->past_IsActive = 1;
- DBUG(("entering thread.\n"));
-
- while( (past->past_StopNow == 0) && (past->past_StopSoon == 0) )
- {
- /* Read data from device */
- if(pahsc->pahsc_NativeInputBuffer)
- {
- unsigned int totalread = 0;
- DBUG(("Pa_AudioThreadProc: attempt to read %d bytes\n", pahsc->pahsc_BytesPerInputBuffer));
- do
- {
- bytes_read = read(pahsc->pahsc_InputHandle,
- (char *)pahsc->pahsc_NativeInputBuffer + totalread,
- pahsc->pahsc_BytesPerInputBuffer - totalread);
-
- if (bytes_read < 0)
- {
- ERR_RPT(("PortAudio: read interrupted!\n"));
- break;
- }
-
- totalread += bytes_read;
- } while( totalread < pahsc->pahsc_BytesPerInputBuffer);
- }
-
- /* Convert 16 bit native data to user data and call user routine. */
- DBUG(("converting...\n"));
- Pa_StartUsageCalculation( past );
- result = Pa_CallConvertInt16( past,
- pahsc->pahsc_NativeInputBuffer,
- pahsc->pahsc_NativeOutputBuffer );
- Pa_EndUsageCalculation( past );
- if( result != 0)
- {
- DBUG(("hmm, Pa_CallConvertInt16() says: %d. i'm bailing.\n",
- result));
- break;
- }
-
- /* Write data to device. */
- if( pahsc->pahsc_NativeOutputBuffer )
- {
- unsigned int totalwritten = 0;
- do
- {
- bytes_written = write(pahsc->pahsc_OutputHandle,
- (void *)pahsc->pahsc_NativeOutputBuffer,
- pahsc->pahsc_BytesPerOutputBuffer);
- if( bytes_written < 0 )
- {
- ERR_RPT(("PortAudio: write interrupted!"));
- break;
- }
-
- totalwritten += bytes_written;
- } while( totalwritten < pahsc->pahsc_BytesPerOutputBuffer);
- }
-
- Pa_UpdateStreamTime(pahsc);
- }
- DBUG(("Pa_AudioThreadProc: left audio loop.\n"));
-
- past->past_IsActive = 0;
- PaHost_StopWatchDog( pahsc );
-
-error:
- DBUG(("leaving audio thread.\n"));
-#ifdef GNUSTEP
- GSUnregisterCurrentThread(); /* SB20010904 */
-#endif
- return result;
-}
-
-/*************************************************************************
-** Determine minimum number of buffers required for this host based
-** on minimum latency. Latency can be optionally set by user by setting
-** an environment variable. For example, to set latency to 200 msec, put:
-**
-** set PA_MIN_LATENCY_MSEC=200
-**
-** in the cshrc file.
-*/
-#define PA_LATENCY_ENV_NAME ("PA_MIN_LATENCY_MSEC")
-
-int Pa_GetMinNumBuffers( int framesPerBuffer, double framesPerSecond )
-{
- int minBuffers;
- int minLatencyMsec = MIN_LATENCY_MSEC;
- char *minLatencyText = getenv(PA_LATENCY_ENV_NAME);
- if( minLatencyText != NULL )
- {
- PRINT(("PA_MIN_LATENCY_MSEC = %s\n", minLatencyText ));
- minLatencyMsec = atoi( minLatencyText );
- if( minLatencyMsec < 1 ) minLatencyMsec = 1;
- else if( minLatencyMsec > 5000 ) minLatencyMsec = 5000;
- }
-
- minBuffers = (int) ((minLatencyMsec * framesPerSecond) / ( 1000.0 * framesPerBuffer ));
- if( minBuffers < 2 ) minBuffers = 2;
- return minBuffers;
-}
-
-/*******************************************************************/
-PaError PaHost_OpenStream( internalPortAudioStream *past )
-{
- PaError result = paNoError;
- PaHostSoundControl *pahsc;
- unsigned int minNumBuffers;
- internalPortAudioDevice *pad;
- DBUG(("PaHost_OpenStream() called.\n" ));
-
- /* Allocate and initialize host data. */
- pahsc = (PaHostSoundControl *) malloc(sizeof(PaHostSoundControl));
- if( pahsc == NULL )
- {
- result = paInsufficientMemory;
- goto error;
- }
- memset( pahsc, 0, sizeof(PaHostSoundControl) );
- past->past_DeviceData = (void *) pahsc;
-
- pahsc->pahsc_OutputHandle = BAD_DEVICE_ID; /* No device currently opened. */
- pahsc->pahsc_InputHandle = BAD_DEVICE_ID;
- pahsc->pahsc_IsAudioThreadValid = 0;
- pahsc->pahsc_IsWatchDogThreadValid = 0;
-
- /* Allocate native buffers. */
- pahsc->pahsc_BytesPerInputBuffer = past->past_FramesPerUserBuffer *
- past->past_NumInputChannels * sizeof(short);
- if( past->past_NumInputChannels > 0)
- {
- pahsc->pahsc_NativeInputBuffer = (short *) malloc(pahsc->pahsc_BytesPerInputBuffer);
- if( pahsc->pahsc_NativeInputBuffer == NULL )
- {
- result = paInsufficientMemory;
- goto error;
- }
- }
- pahsc->pahsc_BytesPerOutputBuffer = past->past_FramesPerUserBuffer *
- past->past_NumOutputChannels * sizeof(short);
- if( past->past_NumOutputChannels > 0)
- {
- pahsc->pahsc_NativeOutputBuffer = (short *) malloc(pahsc->pahsc_BytesPerOutputBuffer);
- if( pahsc->pahsc_NativeOutputBuffer == NULL )
- {
- result = paInsufficientMemory;
- goto error;
- }
- }
-
- /* DBUG(("PaHost_OpenStream: pahsc_MinFramesPerHostBuffer = %d\n", pahsc->pahsc_MinFramesPerHostBuffer )); */
- minNumBuffers = Pa_GetMinNumBuffers( past->past_FramesPerUserBuffer, past->past_SampleRate );
- past->past_NumUserBuffers = ( minNumBuffers > past->past_NumUserBuffers ) ? minNumBuffers : past->past_NumUserBuffers;
-
- pahsc->pahsc_InverseMicrosPerBuffer = past->past_SampleRate / (1000000.0 * past->past_FramesPerUserBuffer);
- DBUG(("past_SampleRate = %g\n", past->past_SampleRate ));
- DBUG(("past_FramesPerUserBuffer = %d\n", past->past_FramesPerUserBuffer ));
- DBUG(("pahsc_InverseMicrosPerBuffer = %g\n", pahsc->pahsc_InverseMicrosPerBuffer ));
-
- /* ------------------------- OPEN DEVICE -----------------------*/
-
- /* just output */
- if (past->past_OutputDeviceID == past->past_InputDeviceID)
- {
-
- if ((past->past_NumOutputChannels > 0) && (past->past_NumInputChannels > 0) )
- {
- pad = Pa_GetInternalDevice( past->past_OutputDeviceID );
- DBUG(("PaHost_OpenStream: attempt to open %s for O_RDWR\n", pad->pad_DeviceName ));
-
- /* dmazzoni: test it first in nonblocking mode to
- make sure the device is not busy */
- pahsc->pahsc_InputHandle = open(pad->pad_DeviceName,O_RDWR|O_NONBLOCK);
- if(pahsc->pahsc_InputHandle==-1)
- {
- ERR_RPT(("PaHost_OpenStream: could not open %s for O_RDWR\n", pad->pad_DeviceName ));
- result = paHostError;
- goto error;
- }
- close(pahsc->pahsc_InputHandle);
-
- pahsc->pahsc_OutputHandle = pahsc->pahsc_InputHandle =
- open(pad->pad_DeviceName,O_RDWR);
- if(pahsc->pahsc_InputHandle==-1)
- {
- ERR_RPT(("PaHost_OpenStream: could not open %s for O_RDWR\n", pad->pad_DeviceName ));
- result = paHostError;
- goto error;
- }
- Pa_SetLatency( pahsc->pahsc_OutputHandle,
- past->past_NumUserBuffers, past->past_FramesPerUserBuffer,
- past->past_NumOutputChannels );
- result = Pa_SetupDeviceFormat( pahsc->pahsc_OutputHandle,
- past->past_NumOutputChannels, (int)past->past_SampleRate );
- }
- }
- else
- {
- if (past->past_NumOutputChannels > 0)
- {
- pad = Pa_GetInternalDevice( past->past_OutputDeviceID );
- DBUG(("PaHost_OpenStream: attempt to open %s for O_WRONLY\n", pad->pad_DeviceName ));
- /* dmazzoni: test it first in nonblocking mode to
- make sure the device is not busy */
- pahsc->pahsc_OutputHandle = open(pad->pad_DeviceName,O_WRONLY|O_NONBLOCK);
- if(pahsc->pahsc_OutputHandle==-1)
- {
- ERR_RPT(("PaHost_OpenStream: could not open %s for O_WRONLY\n", pad->pad_DeviceName ));
- result = paHostError;
- goto error;
- }
- close(pahsc->pahsc_OutputHandle);
-
- pahsc->pahsc_OutputHandle = open(pad->pad_DeviceName,O_WRONLY);
- if(pahsc->pahsc_OutputHandle==-1)
- {
- ERR_RPT(("PaHost_OpenStream: could not open %s for O_WRONLY\n", pad->pad_DeviceName ));
- result = paHostError;
- goto error;
- }
- Pa_SetLatency( pahsc->pahsc_OutputHandle,
- past->past_NumUserBuffers, past->past_FramesPerUserBuffer,
- past->past_NumOutputChannels );
- result = Pa_SetupOutputDeviceFormat( pahsc->pahsc_OutputHandle,
- past->past_NumOutputChannels, (int)past->past_SampleRate );
- }
-
- if (past->past_NumInputChannels > 0)
- {
- pad = Pa_GetInternalDevice( past->past_InputDeviceID );
- DBUG(("PaHost_OpenStream: attempt to open %s for O_RDONLY\n", pad->pad_DeviceName ));
- /* dmazzoni: test it first in nonblocking mode to
- make sure the device is not busy */
- pahsc->pahsc_InputHandle = open(pad->pad_DeviceName,O_RDONLY|O_NONBLOCK);
- if(pahsc->pahsc_InputHandle==-1)
- {
- ERR_RPT(("PaHost_OpenStream: could not open %s for O_RDONLY\n", pad->pad_DeviceName ));
- result = paHostError;
- goto error;
- }
- close(pahsc->pahsc_InputHandle);
-
- pahsc->pahsc_InputHandle = open(pad->pad_DeviceName,O_RDONLY);
- if(pahsc->pahsc_InputHandle==-1)
- {
- ERR_RPT(("PaHost_OpenStream: could not open %s for O_RDONLY\n", pad->pad_DeviceName ));
- result = paHostError;
- goto error;
- }
- Pa_SetLatency( pahsc->pahsc_InputHandle, /* DH20010115 - was OutputHandle! */
- past->past_NumUserBuffers, past->past_FramesPerUserBuffer,
- past->past_NumInputChannels );
- result = Pa_SetupInputDeviceFormat( pahsc->pahsc_InputHandle,
- past->past_NumInputChannels, (int)past->past_SampleRate );
- }
- }
-
-
- DBUG(("PaHost_OpenStream: SUCCESS - result = %d\n", result ));
- return result;
-
-error:
- ERR_RPT(("PaHost_OpenStream: ERROR - result = %d\n", result ));
- PaHost_CloseStream( past );
- return result;
-}
-
-/*************************************************************************/
-PaError PaHost_StartOutput( internalPortAudioStream *past )
-{
- past = past; /* unused */
- return paNoError;
-}
-
-/*************************************************************************/
-PaError PaHost_StartInput( internalPortAudioStream *past )
-{
- past = past; /* unused */
- return paNoError;
-}
-
-/*************************************************************************/
-PaError PaHost_StartEngine( internalPortAudioStream *past )
-{
- PaHostSoundControl *pahsc;
- PaError result = paNoError;
- int hres;
-
- pahsc = (PaHostSoundControl *) past->past_DeviceData;
-
- past->past_StopSoon = 0;
- past->past_StopNow = 0;
- past->past_IsActive = 1;
-
- /* Use pthread_create() instead of __clone() because:
- * - pthread_create also works for other UNIX systems like Solaris,
- * - the Java HotSpot VM crashes in pthread_setcanceltype() when using __clone()
- */
- hres = pthread_create(&(pahsc->pahsc_AudioThread),
- NULL /*pthread_attr_t * attr*/,
- (pthread_function_t)Pa_AudioThreadProc, past);
- if( hres != 0 )
- {
- result = paHostError;
- sPaHostError = hres;
- pahsc->pahsc_IsAudioThreadValid = 0;
- goto error;
- }
- pahsc->pahsc_IsAudioThreadValid = 1;
-
-error:
- return result;
-}
-
-/*************************************************************************/
-PaError PaHost_StopEngine( internalPortAudioStream *past, int abort )
-{
- int hres;
- PaError result = paNoError;
- PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;
-
- if( pahsc == NULL ) return paNoError;
-
- /* Tell background thread to stop generating more data and to let current data play out. */
- past->past_StopSoon = 1;
- /* If aborting, tell background thread to stop NOW! */
- if( abort ) past->past_StopNow = 1;
-
- /* Join thread to recover memory resources. */
- if( pahsc->pahsc_IsAudioThreadValid )
- {
- /* This check is needed for GNUSTEP - SB20010904 */
- if ( !pthread_equal( pahsc->pahsc_AudioThread, pthread_self() ) )
- {
- hres = pthread_join( pahsc->pahsc_AudioThread, NULL );
- }
- else
- {
- DBUG(("Play thread was stopped from itself - can't do pthread_join()\n"));
- hres = 0;
- }
-
- if( hres != 0 )
- {
- result = paHostError;
- sPaHostError = hres;
- }
- pahsc->pahsc_IsAudioThreadValid = 0;
- }
-
- past->past_IsActive = 0;
-
- return result;
-}
-
-/*************************************************************************/
-PaError PaHost_StopInput( internalPortAudioStream *past, int abort )
-{
- past = past; /* unused */
- abort = abort; /* unused */
- return paNoError;
-}
-
-/*************************************************************************/
-PaError PaHost_StopOutput( internalPortAudioStream *past, int abort )
-{
- past = past; /* unused */
- abort = abort; /* unused */
- return paNoError;
-}
-
-/*******************************************************************/
-PaError PaHost_CloseStream( internalPortAudioStream *past )
-{
- PaHostSoundControl *pahsc;
-
- if( past == NULL ) return paBadStreamPtr;
- pahsc = (PaHostSoundControl *) past->past_DeviceData;
- if( pahsc == NULL ) return paNoError;
-
- if( pahsc->pahsc_OutputHandle != BAD_DEVICE_ID )
- {
- int err = 0;
- DBUG(("PaHost_CloseStream: attempt to close output device handle = %d\n",
- pahsc->pahsc_OutputHandle ));
-
- Pa_FlushStream(pahsc->pahsc_OutputHandle);
-
- err = close(pahsc->pahsc_OutputHandle);
- if( err < 0 )
- {
- ERR_RPT(("PaHost_CloseStream: warning, closing output device failed.\n"));
- }
- }
-
- if( (pahsc->pahsc_InputHandle != BAD_DEVICE_ID) &&
- (pahsc->pahsc_InputHandle != pahsc->pahsc_OutputHandle) )
- {
- int err = 0;
- DBUG(("PaHost_CloseStream: attempt to close input device handle = %d\n",
- pahsc->pahsc_InputHandle ));
-
- Pa_FlushStream(pahsc->pahsc_InputHandle);
-
- err = close(pahsc->pahsc_InputHandle);
- if( err < 0 )
- {
- ERR_RPT(("PaHost_CloseStream: warning, closing input device failed.\n"));
- }
- }
- pahsc->pahsc_OutputHandle = BAD_DEVICE_ID;
- pahsc->pahsc_InputHandle = BAD_DEVICE_ID;
-
- if( pahsc->pahsc_NativeInputBuffer )
- {
- free( pahsc->pahsc_NativeInputBuffer );
- pahsc->pahsc_NativeInputBuffer = NULL;
- }
- if( pahsc->pahsc_NativeOutputBuffer )
- {
- free( pahsc->pahsc_NativeOutputBuffer );
- pahsc->pahsc_NativeOutputBuffer = NULL;
- }
-
- free( pahsc );
- past->past_DeviceData = NULL;
- return paNoError;
-}
-
-/*************************************************************************/
-PaError PaHost_Term( void )
-{
- /* Free all of the linked devices. */
- internalPortAudioDevice *pad, *nextPad;
- pad = sDeviceList;
- while( pad != NULL )
- {
- nextPad = pad->pad_Next;
- DBUG(("PaHost_Term: freeing %s\n", pad->pad_DeviceName ));
- PaHost_FreeFastMemory( pad, sizeof(internalPortAudioDevice) );
- pad = nextPad;
- }
- sDeviceList = NULL;
- return 0;
-}
-
-/*************************************************************************
- * Sleep for the requested number of milliseconds.
- */
-void Pa_Sleep( int32_t msec )
-{
-#if 0
- struct timeval timeout;
- timeout.tv_sec = msec / 1000;
- timeout.tv_usec = (msec % 1000) * 1000;
- select( 0, NULL, NULL, NULL, &timeout );
-#else
- int32_t usecs = msec * 1000;
- usleep( usecs );
-#endif
-}
-
-/*************************************************************************
- * Allocate memory that can be accessed in real-time.
- * This may need to be held in physical memory so that it is not
- * paged to virtual memory.
- * This call MUST be balanced with a call to PaHost_FreeFastMemory().
- */
-void *PaHost_AllocateFastMemory( int32_t numBytes )
-{
- void *addr = malloc( numBytes ); /* FIXME - do we need physical, wired, non-virtual memory? */
- if( addr != NULL ) memset( addr, 0, numBytes );
- return addr;
-}
-
-/*************************************************************************
- * Free memory that could be accessed in real-time.
- * This call MUST be balanced with a call to PaHost_AllocateFastMemory().
- */
-void PaHost_FreeFastMemory( void *addr, int32_t numBytes )
-{
- numBytes = numBytes; /* unused */
- if( addr != NULL ) free( addr );
-}
-
-
-/***********************************************************************/
-PaError PaHost_StreamActive( internalPortAudioStream *past )
-{
- PaHostSoundControl *pahsc;
- if( past == NULL ) return paBadStreamPtr;
- pahsc = (PaHostSoundControl *) past->past_DeviceData;
- if( pahsc == NULL ) return paInternalError;
- return (PaError) (past->past_IsActive != 0);
-}
-
-/***********************************************************************/
-int32_t Pa_GetHostError( void )
-{
- return (long) sPaHostError;
-}
-
-
-#endif // HAVE_LINUX
diff --git a/lib/portaudio/pa_unix.h b/lib/portaudio/pa_unix.h
deleted file mode 100644
index 4501002..0000000
--- a/lib/portaudio/pa_unix.h
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * PortAudio Portable Real-Time Audio Library
- * Latest Version at: http://www.portaudio.com
- * Linux OSS Implementation by douglas repetto and Phil Burk
- *
- * Copyright (c) 1999-2000 Phil Burk
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files
- * (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * Any person wishing to distribute modifications to the Software is
- * requested to send the modifications to the original developer so that
- * they can be incorporated into the canonical version.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- */
-
-/* Modification history:
- 20020621: pa_unix_oss.c split into pa_unix.c, pa_unix.h, pa_unix_oss.c by
- Augustus Saunders. See pa_unix.c for previous history. */
-
-/*
- PROPOSED - should we add this to "portaudio.h". Problem with
- Pa_QueryDevice() not having same driver name os Pa_OpenStream().
-
- A PaDriverInfo structure can be passed to the underlying device
- on the Pa_OpenStream() call. The contents and interpretation of
- the structure is determined by the PA implementation.
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-//#include <malloc.h>
-#include <memory.h>
-#include <math.h>
-#include <sys/ioctl.h>
-#include <sys/time.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <signal.h>
-#include <sched.h>
-#include <pthread.h>
-#include <errno.h>
-
-#include "portaudio.h"
-#include "pa_host.h"
-#include "pa_trace.h"
-
-#define PRINT(x) { printf x; fflush(stdout); }
-#define ERR_RPT(x) PRINT(x)
-#define DBUG(x) /* PRINT(x) */
-#define DBUGX(x) /* PRINT(x) */
-
-#define BAD_DEVICE_ID (-1)
-
-#define MIN_LATENCY_MSEC (100)
-#define MIN_TIMEOUT_MSEC (100)
-#define MAX_TIMEOUT_MSEC (1000)
-
-/************************************************* Definitions ********/
-#ifdef __linux__
- #define DEVICE_NAME_BASE "/dev/dsp"
-#else
- #define DEVICE_NAME_BASE "/dev/audio"
-#endif
-
-typedef struct PaDriverInfo /* PROPOSED */
-{
- /* Size of structure. Allows driver to extend the structure without breaking existing applications. */
- int size;
- /* Can be used to request a specific device name. */
- const char *name;
- uint32_t data;
-}
-PaDriverInfo;
-
-#define MAX_CHARS_DEVNAME (32)
-#define MAX_SAMPLE_RATES (10)
-typedef struct internalPortAudioDevice
-{
- struct internalPortAudioDevice *pad_Next; /* Singly linked list. */
- double pad_SampleRates[MAX_SAMPLE_RATES]; /* for pointing to from pad_Info */
- char pad_DeviceName[MAX_CHARS_DEVNAME];
- PaDeviceInfo pad_Info;
-}
-internalPortAudioDevice;
-
-/* Define structure to contain all OSS and Linux specific data. */
-typedef struct PaHostSoundControl
-{
- int pahsc_OutputHandle;
- int pahsc_InputHandle;
- int pahsc_AudioPriority; /* priority of background audio thread */
- pthread_t pahsc_AudioThread; /* background audio thread */
- int pahsc_IsAudioThreadValid; /* Is pahsc_AudioThread valid?*/ pid_t pahsc_AudioThreadPID; /* background audio thread */
- pthread_t pahsc_WatchDogThread; /* highest priority thread that protects system */
- int pahsc_IsWatchDogThreadValid; /* Is pahsc_WatchDogThread valid?*/
- int pahsc_WatchDogRun; /* Ask WatchDog to stop. */
- pthread_t pahsc_CanaryThread; /* low priority thread that detects abuse by audio */
- int pahsc_IsCanaryThreadValid; /* Is pahsc_CanaryThread valid?*/
- struct timeval pahsc_CanaryTime;
- int pahsc_CanaryRun; /* Ask Canary to stop. */
- short *pahsc_NativeInputBuffer;
- short *pahsc_NativeOutputBuffer;
- unsigned int pahsc_BytesPerInputBuffer; /* native buffer size in bytes */
- unsigned int pahsc_BytesPerOutputBuffer; /* native buffer size in bytes */
- /* For measuring CPU utilization. */
- struct timeval pahsc_EntryTime;
- double pahsc_InverseMicrosPerBuffer; /* 1/Microseconds of real-time audio per user buffer. */
-
- /* For calculating stream time */
- int pahsc_LastPosPtr;
- double pahsc_LastStreamBytes;
-}
-PaHostSoundControl;
-
-/************************************************* Prototypes **********/
-
-internalPortAudioDevice *Pa_GetInternalDevice( PaDeviceID id );
-PaError Pa_QueryDevices( void );
-PaError Pa_QueryDevice( const char *deviceName, internalPortAudioDevice *pad );
-PaError Pa_SetupDeviceFormat( int devHandle, int numChannels, int sampleRate );
-PaError Pa_SetupInputDeviceFormat( int devHandle, int numChannels, int sampleRate );
-PaError Pa_SetupOutputDeviceFormat( int devHandle, int numChannels, int sampleRate );
-void Pa_SetLatency( int devHandle, int numBuffers, int framesPerBuffer, int channelsPerFrame );
-void Pa_UpdateStreamTime(PaHostSoundControl *pahsc);
-int Pa_FlushStream(int devHandle);
diff --git a/lib/portaudio/pa_unix_oss.c b/lib/portaudio/pa_unix_oss.c
deleted file mode 100644
index 9b2274c..0000000
--- a/lib/portaudio/pa_unix_oss.c
+++ /dev/null
@@ -1,395 +0,0 @@
-/*
- * PortAudio Portable Real-Time Audio Library
- * Latest Version at: http://www.portaudio.com
- * Linux OSS Implementation by douglas repetto and Phil Burk
- *
- * Copyright (c) 1999-2000 Phil Burk
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files
- * (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * Any person wishing to distribute modifications to the Software is
- * requested to send the modifications to the original developer so that
- * they can be incorporated into the canonical version.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- */
-
-/* Modification history:
- 20020621: pa_unix_oss.c split into pa_unix.c, pa_unix.h, pa_unix_oss.c by
- Augustus Saunders. See pa_unix.c for previous history. Pa_FlushStream
- added by Augustus Saunders for Solaris compatibility.
- PLB20021018 - Fill device info table with actual sample rates instead of wished for rates.
- - Allow stream to open if sample rate within 10% of desired rate.
- 20030630 - Thomas Richter - eliminated unused variable warnings.
-*/
-
-#include <config.h>
-#ifdef HAVE_UNIX
-
-#include "pa_unix.h"
-
-#ifdef HAVE_LINUX
-#include <linux/soundcard.h>
-#else
-
-#ifdef HAVE_BSD
-#include <sys/soundcard.h>
-#else
-#include <machine/soundcard.h> /* JH20010905 */
-#endif
-
-#endif
-
-#ifndef AFMT_S16_NE
-#define AFMT_S16_NE Get_AFMT_S16_NE()
-/*********************************************************************
- * Some versions of OSS do not define AFMT_S16_NE. So check CPU.
- * PowerPC is Big Endian. X86 is Little Endian.
- */
-int Get_AFMT_S16_NE( void )
-{
- int32_t testData = 1;
- char *ptr = (char *) &testData;
- int isLittle = ( *ptr == 1 ); /* Does address point to least significant byte? */
- return isLittle ? AFMT_S16_LE : AFMT_S16_BE;
-}
-#endif /* AFMT_S16_NE */
-
-
-/*********************************************************************
- * Try to open the named device.
- * If it opens, try to set various rates and formats and fill in
- * the device info structure.
- */
-PaError Pa_QueryDevice( const char *deviceName, internalPortAudioDevice *pad )
-{
- int result = paHostError;
- int tempDevHandle;
- int numChannels, maxNumChannels;
- int format;
- int numSampleRates;
- int sampleRate;
- int numRatesToTry;
- int lastRate;
- int ratesToTry[9] = {96000, 48000, 44100, 32000, 24000, 22050, 16000, 11025, 8000};
- int i;
-
- /* douglas:
- we have to do this querying in a slightly different order. apparently
- some sound cards will give you different info based on their settings.
- e.g. a card might give you stereo at 22kHz but only mono at 44kHz.
- the correct order for OSS is: format, channels, sample rate
-
- */
- if ( (tempDevHandle = open(deviceName,O_WRONLY|O_NONBLOCK)) == -1 )
- {
- DBUG(("Pa_QueryDevice: could not open %s\n", deviceName ));
- return paHostError;
- }
-
- /* Ask OSS what formats are supported by the hardware. */
- pad->pad_Info.nativeSampleFormats = 0;
-
- if (ioctl(tempDevHandle, SNDCTL_DSP_GETFMTS, &format) == -1)
- {
- ERR_RPT(("Pa_QueryDevice: could not get format info\n" ));
- goto error;
- }
- if( format & AFMT_U8 ) pad->pad_Info.nativeSampleFormats |= paUInt8;
- if( format & AFMT_S16_NE ) pad->pad_Info.nativeSampleFormats |= paInt16;
-
- /* Negotiate for the maximum number of channels for this device. PLB20010927
- * Consider up to 16 as the upper number of channels.
- * Variable numChannels should contain the actual upper limit after the call.
- * Thanks to John Lazzaro and Heiko Purnhagen for suggestions.
- */
- maxNumChannels = 0;
- for( numChannels = 1; numChannels <= 16; numChannels++ )
- {
- int temp = numChannels;
- DBUG(("Pa_QueryDevice: use SNDCTL_DSP_CHANNELS, numChannels = %d\n", numChannels ))
- if(ioctl(tempDevHandle, SNDCTL_DSP_CHANNELS, &temp) < 0 )
- {
- /* ioctl() failed so bail out if we already have stereo */
- if( numChannels > 2 ) break;
- }
- else
- {
- /* ioctl() worked but bail out if it does not support numChannels.
- * We don't want to leave gaps in the numChannels supported.
- */
- if( (numChannels > 2) && (temp != numChannels) ) break;
- DBUG(("Pa_QueryDevice: temp = %d\n", temp ))
- if( temp > maxNumChannels ) maxNumChannels = temp; /* Save maximum. */
- }
- }
-
- /* The above negotiation may fail for an old driver so try this older technique. */
- if( maxNumChannels < 1 )
- {
- int stereo = 1;
- if(ioctl(tempDevHandle, SNDCTL_DSP_STEREO, &stereo) < 0)
- {
- maxNumChannels = 1;
- }
- else
- {
- maxNumChannels = (stereo) ? 2 : 1;
- }
- DBUG(("Pa_QueryDevice: use SNDCTL_DSP_STEREO, maxNumChannels = %d\n", maxNumChannels ))
- }
-
- pad->pad_Info.maxOutputChannels = maxNumChannels;
- DBUG(("Pa_QueryDevice: maxNumChannels = %d\n", maxNumChannels))
-
- /* During channel negotiation, the last ioctl() may have failed. This can
- * also cause sample rate negotiation to fail. Hence the following, to return
- * to a supported number of channels. SG20011005 */
- {
- int temp = maxNumChannels;
- if( temp > 2 ) temp = 2; /* use most reasonable default value */
- ioctl(tempDevHandle, SNDCTL_DSP_CHANNELS, &temp);
- }
-
- /* FIXME - for now, assume maxInputChannels = maxOutputChannels.
- * Eventually do separate queries for O_WRONLY and O_RDONLY
- */
- pad->pad_Info.maxInputChannels = pad->pad_Info.maxOutputChannels;
-
- DBUG(("Pa_QueryDevice: maxInputChannels = %d\n",
- pad->pad_Info.maxInputChannels))
-
-
- /* Determine available sample rates by trying each one and seeing result.
- * OSS often supports funky rates such as 44188 instead of 44100!
- */
- numSampleRates = 0;
- lastRate = 0;
- numRatesToTry = sizeof(ratesToTry)/sizeof(int);
- for (i = 0; i < numRatesToTry; i++)
- {
- sampleRate = ratesToTry[i];
-
- if (ioctl(tempDevHandle, SNDCTL_DSP_SPEED, &sampleRate) >= 0 ) /* PLB20010817 */
- {
- /* Use whatever rate OSS tells us. PLB20021018 */
- if (sampleRate != lastRate)
- {
- DBUG(("Pa_QueryDevice: adding sample rate: %d\n", sampleRate))
- pad->pad_SampleRates[numSampleRates] = (float)sampleRate;
- numSampleRates++;
- lastRate = sampleRate;
- }
- else
- {
- DBUG(("Pa_QueryDevice: dang - got sample rate %d again!\n", sampleRate))
- }
- }
- }
-
- DBUG(("Pa_QueryDevice: final numSampleRates = %d\n", numSampleRates))
- if (numSampleRates==0) /* HP20010922 */
- {
- /* Desparate attempt to keep running even though no good rates found! */
- ERR_RPT(("Pa_QueryDevice: no supported sample rate (or SNDCTL_DSP_SPEED ioctl call failed). Force 44100 Hz\n" ));
- pad->pad_SampleRates[numSampleRates++] = 44100;
- }
-
- pad->pad_Info.numSampleRates = numSampleRates;
- pad->pad_Info.sampleRates = pad->pad_SampleRates; /* use pointer to embedded array */
-
- pad->pad_Info.name = deviceName;
-
- result = paNoError;
-
-error:
- /* We MUST close the handle here or we won't be able to reopen it later!!! */
- close(tempDevHandle);
-
- return result;
-}
-
-/*******************************************************************************************/
-PaError Pa_SetupDeviceFormat( int devHandle, int numChannels, int sampleRate )
-{
- PaError result = paNoError;
- int tmp;
-
- /* Set format, channels, and rate in this order to keep OSS happy. */
- /* Set data format. FIXME - handle more native formats. */
- tmp = AFMT_S16_NE;
- if( ioctl(devHandle,SNDCTL_DSP_SETFMT,&tmp) == -1)
- {
- ERR_RPT(("Pa_SetupDeviceFormat: could not SNDCTL_DSP_SETFMT\n" ));
- return paHostError;
- }
- if( tmp != AFMT_S16_NE )
- {
- ERR_RPT(("Pa_SetupDeviceFormat: HW does not support AFMT_S16_NE\n" ));
- return paHostError;
- }
-
-
- /* Set number of channels. */
- tmp = numChannels;
- if (ioctl(devHandle, SNDCTL_DSP_CHANNELS, &numChannels) == -1)
- {
- ERR_RPT(("Pa_SetupDeviceFormat: could not SNDCTL_DSP_CHANNELS\n" ));
- return paHostError;
- }
- if( tmp != numChannels)
- {
- ERR_RPT(("Pa_SetupDeviceFormat: HW does not support %d channels\n", numChannels ));
- return paHostError;
- }
-
- /* Set playing frequency. */
- tmp = sampleRate;
- if( ioctl(devHandle,SNDCTL_DSP_SPEED,&tmp) == -1)
- {
- ERR_RPT(("Pa_SetupDeviceFormat: could not SNDCTL_DSP_SPEED\n" ));
- return paHostError;
- }
- else if( tmp != sampleRate )
- {
- int percentError = abs( (100 * (sampleRate - tmp)) / sampleRate );
- PRINT(("Pa_SetupDeviceFormat: warning - requested sample rate = %d Hz - closest = %d\n",
- sampleRate, tmp ));
- /* Allow sample rate within 10% off of requested rate. PLB20021018
- * Sometimes OSS uses a funky rate like 44188 instead of 44100.
- */
- if( percentError > 10 )
- {
- ERR_RPT(("Pa_SetupDeviceFormat: HW does not support %d Hz sample rate\n",sampleRate ));
- return paHostError;
- }
- }
-
- return result;
-}
-
-PaError Pa_SetupOutputDeviceFormat( int devHandle, int numChannels, int sampleRate )
-{
- return Pa_SetupDeviceFormat(devHandle, numChannels, sampleRate);
-}
-
-PaError Pa_SetupInputDeviceFormat( int devHandle, int numChannels, int sampleRate )
-{
- return Pa_SetupDeviceFormat(devHandle, numChannels, sampleRate);
-}
-
-
-/*******************************************************************************************
-** Set number of fragments and size of fragments to achieve desired latency.
-*/
-
-static int CalcHigherLogTwo( int n )
-{
- int log2 = 0;
- while( (1<<log2) < n ) log2++;
- return log2;
-}
-
-void Pa_SetLatency( int devHandle, int numBuffers, int framesPerBuffer, int channelsPerFrame )
-{
- int tmp;
- int bufferSize, powerOfTwo;
-
- /* Increase size of buffers and reduce number of buffers to reduce latency inside driver. */
- while( numBuffers > 8 )
- {
- numBuffers = (numBuffers + 1) >> 1;
- framesPerBuffer = framesPerBuffer << 1;
- }
-
- /* calculate size of buffers in bytes */
- bufferSize = framesPerBuffer * channelsPerFrame * sizeof(short); /* FIXME - other sizes? */
-
- /* Calculate next largest power of two */
- powerOfTwo = CalcHigherLogTwo( bufferSize );
- DBUG(("Pa_SetLatency: numBuffers = %d, framesPerBuffer = %d, powerOfTwo = %d\n",
- numBuffers, framesPerBuffer, powerOfTwo ));
-
- /* Encode info into a single int */
- tmp=(numBuffers<<16) + powerOfTwo;
-
- if(ioctl(devHandle,SNDCTL_DSP_SETFRAGMENT,&tmp) == -1)
- {
- ERR_RPT(("Pa_SetLatency: could not SNDCTL_DSP_SETFRAGMENT\n" ));
- /* Don't return an error. Best to just continue and hope for the best. */
- ERR_RPT(("Pa_SetLatency: numBuffers = %d, framesPerBuffer = %d, powerOfTwo = %d\n",
- numBuffers, framesPerBuffer, powerOfTwo ));
- }
-}
-
-/***********************************************************************/
-PaTimestamp Pa_StreamTime( PortAudioStream *stream )
-{
- internalPortAudioStream *past = (internalPortAudioStream *) stream;
- PaHostSoundControl *pahsc;
-
- count_info info;
- int delta;
-
- if( past == NULL ) return paBadStreamPtr;
-
- pahsc = (PaHostSoundControl *) past->past_DeviceData;
-
- if( pahsc->pahsc_NativeOutputBuffer )
- {
- ioctl(pahsc->pahsc_OutputHandle, SNDCTL_DSP_GETOPTR, &info);
- delta = (info.bytes - pahsc->pahsc_LastPosPtr) & 0x000FFFFF;
- return (pahsc->pahsc_LastStreamBytes + delta) / (past->past_NumOutputChannels * sizeof(short));
- }
- else
- {
- ioctl(pahsc->pahsc_InputHandle, SNDCTL_DSP_GETIPTR, &info);
- delta = (info.bytes - pahsc->pahsc_LastPosPtr) & 0x000FFFFF;
- return (pahsc->pahsc_LastStreamBytes + delta) / (past->past_NumInputChannels * sizeof(short));
- }
-}
-
-void Pa_UpdateStreamTime(PaHostSoundControl *pahsc)
-{
- count_info info;
- int delta;
-
- /* Update current stream time (using a double so that
- we don't wrap around like info.bytes does) */
- if( pahsc->pahsc_NativeOutputBuffer )
- {
- ioctl(pahsc->pahsc_OutputHandle, SNDCTL_DSP_GETOPTR, &info);
- }
- else
- {
- ioctl(pahsc->pahsc_InputHandle, SNDCTL_DSP_GETIPTR, &info);
- }
- delta = (info.bytes - pahsc->pahsc_LastPosPtr) & 0x000FFFFF;
- pahsc->pahsc_LastStreamBytes += delta;
- pahsc->pahsc_LastPosPtr = info.bytes;
-}
-
-PaError Pa_FlushStream(int devHandle)
-{
- /* AS: This doesn't do anything under OSS; it was added for Solaris.*/
- devHandle = devHandle; /* unused */
- return paNoError;
-}
-
-#endif // HAVE_LINUX
diff --git a/lib/portaudio/pa_unix_solaris.c b/lib/portaudio/pa_unix_solaris.c
deleted file mode 100644
index c2102af..0000000
--- a/lib/portaudio/pa_unix_solaris.c
+++ /dev/null
@@ -1,402 +0,0 @@
-/*
- * PortAudio Portable Real-Time Audio Library
- * Latest Version at: http://www.portaudio.com
- * Linux OSS Implementation by douglas repetto and Phil Burk
- *
- * Copyright (c) 1999-2000 Phil Burk
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files
- * (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * Any person wishing to distribute modifications to the Software is
- * requested to send the modifications to the original developer so that
- * they can be incorporated into the canonical version.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- */
-
-/* Modification history:
- 20020621: Initial cut at Solaris modifications jointly by Sam Bayer
- and Augustus Saunders.
- 20030206 - Martin Rohrbach - various mods for Solaris
- */
-
-#include <config.h>
-#ifdef HAVE_SOLARIS
-
-#define __solaris_native__
-
-#include "pa_unix.h"
-
-/* SAM 6/2/02: Docs say we should include sys/audio.h, but
- that doesn't exist pre Solaris 2.8. These headers work fine. */
-
-#include <sys/audioio.h>
-#include <sys/stropts.h>
-
-/*********************************************************************
- * Try to open the named device.
- * If it opens, try to set various rates and formats and fill in
- * the device info structure.
- */
-PaError Pa_QueryDevice( const char *deviceName, internalPortAudioDevice *pad )
-{
- int result = paHostError;
- int tempDevHandle;
- int numChannels, maxNumChannels;
- int numSampleRates;
- int sampleRate;
- int numRatesToTry;
- int ratesToTry[9] = {96000, 48000, 44100, 32000, 24000, 22050, 16000, 11025, 8000};
- int i;
- audio_info_t solaris_info;
- audio_device_t device_info;
-
- /* douglas:
- we have to do this querying in a slightly different order. apparently
- some sound cards will give you different info based on their settins.
- e.g. a card might give you stereo at 22kHz but only mono at 44kHz.
- the correct order for OSS is: format, channels, sample rate
-
- */
- /*
- to check a device for it's capabilities, it's probably better to use the
- equivalent "-ctl"-descriptor - MR
- */
- char devname[strlen(deviceName) + 4];
- if ( (tempDevHandle = open(strcat(strcpy(devname, deviceName), "ctl"), O_WRONLY|O_NONBLOCK)) == -1 )
- {
- DBUG(("Pa_QueryDevice: could not open %s\n", deviceName ));
- return paHostError;
- }
-
- /* Ask OSS what formats are supported by the hardware. */
- pad->pad_Info.nativeSampleFormats = 0;
- AUDIO_INITINFO(&solaris_info);
-
- /* SAM 12/31/01: Sparc native does mulaw, alaw and PCM.
- I think PCM is signed. */
-
- for (i = 8; i <= 32; i += 8) {
- solaris_info.play.precision = i;
- solaris_info.play.encoding = AUDIO_ENCODING_LINEAR;
- /* If there are no errors, add the format. */
- if (ioctl(tempDevHandle, AUDIO_SETINFO, &solaris_info) > -1) {
- switch (i) {
- case 8:
- pad->pad_Info.nativeSampleFormats |= paInt8;
- break;
- case 16:
- pad->pad_Info.nativeSampleFormats |= paInt16;
- break;
- case 24:
- pad->pad_Info.nativeSampleFormats |= paInt24;
- break;
- case 32:
- pad->pad_Info.nativeSampleFormats |= paInt32;
- break;
- }
- }
- }
-
- maxNumChannels = 0;
- for( numChannels = 1; numChannels <= 16; numChannels++ )
- {
- int temp = numChannels;
- DBUG(("Pa_QueryDevice: use SNDCTL_DSP_CHANNELS, numChannels = %d\n", numChannels ))
- AUDIO_INITINFO(&solaris_info);
- solaris_info.play.channels = temp;
- if (ioctl(tempDevHandle, AUDIO_SETINFO, &solaris_info) < 0)
- {
- /* ioctl() failed so bail out if we already have stereo */
- if( numChannels > 2 ) break;
- }
- else
- {
- /* ioctl() worked but bail out if it does not support numChannels.
- * We don't want to leave gaps in the numChannels supported.
- */
- if( (numChannels > 2) && (temp != numChannels) ) break;
- DBUG(("Pa_QueryDevice: temp = %d\n", temp ))
- if( temp > maxNumChannels ) maxNumChannels = temp; /* Save maximum. */
- }
- }
-
- pad->pad_Info.maxOutputChannels = maxNumChannels;
- DBUG(("Pa_QueryDevice: maxNumChannels = %d\n", maxNumChannels))
-
- /* FIXME - for now, assume maxInputChannels = maxOutputChannels.
- * Eventually do separate queries for O_WRONLY and O_RDONLY
- */
- pad->pad_Info.maxInputChannels = pad->pad_Info.maxOutputChannels;
-
- DBUG(("Pa_QueryDevice: maxInputChannels = %d\n",
- pad->pad_Info.maxInputChannels))
-
-
- /* Determine available sample rates by trying each one and seeing result.
- */
- numSampleRates = 0;
-
- AUDIO_INITINFO(&solaris_info);
-
- numRatesToTry = sizeof(ratesToTry)/sizeof(int);
- for (i = 0; i < numRatesToTry; i++)
- {
- sampleRate = ratesToTry[i];
-
- solaris_info.play.sample_rate = sampleRate; /* AS: We opened for Write, so set play */
- if (ioctl(tempDevHandle, AUDIO_SETINFO, &solaris_info) >= 0 ) /* PLB20010817 */
- {
- if (sampleRate == ratesToTry[i])
- {
- DBUG(("Pa_QueryDevice: got sample rate: %d\n", sampleRate))
- pad->pad_SampleRates[numSampleRates] = (float)ratesToTry[i];
- numSampleRates++;
- }
- }
- }
-
- DBUG(("Pa_QueryDevice: final numSampleRates = %d\n", numSampleRates))
- if (numSampleRates==0) /* HP20010922 */
- {
- ERR_RPT(("Pa_QueryDevice: no supported sample rate (or SNDCTL_DSP_SPEED ioctl call failed).\n" ));
- goto error;
- }
-
- pad->pad_Info.numSampleRates = numSampleRates;
- pad->pad_Info.sampleRates = pad->pad_SampleRates;
-
- /* query for the device name instead of using the filesystem-device - MR */
- if (ioctl(tempDevHandle, AUDIO_GETDEV, &device_info) == -1) {
- pad->pad_Info.name = deviceName;
- } else {
- char *pt = (char *)PaHost_AllocateFastMemory(strlen(device_info.name));
- strcpy(pt, device_info.name);
- pad->pad_Info.name = pt;
- }
-
- result = paNoError;
-
-error:
- /* We MUST close the handle here or we won't be able to reopen it later!!! */
- close(tempDevHandle);
-
- return result;
-}
-
-/*******************************************************************************************/
-
-PaError Pa_SetupInputDeviceFormat( int devHandle, int numChannels, int sampleRate )
-{
- audio_info_t solaris_info;
- AUDIO_INITINFO(&solaris_info);
-
- /* Sam Bayer/Bryan George 1/10/02: Various folks have
- reported that on Solaris Ultra II, the not-right thing
- happens on read unless you make sure the audio device is
- flushed. The folks who wrote the Robust Audio Tool say:
- + XXX driver issue - on Ultra II's if you don't drain
- * the device before reading commences then the device
- * reads in blocks of 500ms irrespective of the
- * blocksize set. After a minute or so it flips into the
- * correct mode, but obviously this is too late to be + * useful for most apps. grrr.
- */
- /* AS: And the Solaris man audio pages say you should flush before changing formats
- anyway. So there you go. */
- if (Pa_FlushStream(devHandle) != paNoError)
- return paHostError;
-
- solaris_info.record.encoding = AUDIO_ENCODING_LINEAR;
- solaris_info.record.sample_rate = sampleRate;
- solaris_info.record.precision = 16;
- solaris_info.record.channels = numChannels;
-
- if (ioctl(devHandle, AUDIO_SETINFO, &solaris_info) == -1)
- {
- ERR_RPT(("Pa_SetupDeviceFormat: could not set audio info\n" ));
- return paHostError;
- }
-
- return paNoError;
-}
-
-PaError Pa_SetupOutputDeviceFormat( int devHandle, int numChannels, int sampleRate )
-{
- audio_info_t solaris_info;
- AUDIO_INITINFO(&solaris_info);
-
- /* Sam Bayer/Bryan George 1/10/02: Various folks have
- reported that on Solaris Ultra II, the not-right thing
- happens on read unless you make sure the audio device is
- flushed. The folks who wrote the Robust Audio Tool say:
- + XXX driver issue - on Ultra II's if you don't drain
- * the device before reading commences then the device
- * reads in blocks of 500ms irrespective of the
- * blocksize set. After a minute or so it flips into the
- * correct mode, but obviously this is too late to be + * useful for most apps. grrr.
- */
- /* AS: And the Solaris man audio pages say you should flush before changing formats
- anyway. So there you go. */
- if (Pa_FlushStream(devHandle) != paNoError)
- return paHostError;
-
- solaris_info.play.encoding = AUDIO_ENCODING_LINEAR;
- solaris_info.play.sample_rate = sampleRate;
- solaris_info.play.precision = 16;
- solaris_info.play.channels = numChannels;
-
- if (ioctl(devHandle, AUDIO_SETINFO, &solaris_info) == -1)
- {
- ERR_RPT(("Pa_SetupDeviceFormat: could not set audio info\n" ));
- return paHostError;
- }
-
- return paNoError;
-}
-
-PaError Pa_SetupDeviceFormat( int devHandle, int numChannels, int sampleRate )
-{
- PaError result = paNoError;
-
- result = Pa_SetupOutputDeviceFormat(devHandle, numChannels, sampleRate);
- if (result != paNoError)
- return result;
- return Pa_SetupInputDeviceFormat(devHandle, numChannels, sampleRate);
-}
-
-/*******************************************************************************************
-** Set number of fragments and size of fragments to achieve desired latency.
-*/
-
-static PaError Pa_Unpause(int devHandle);
-static PaError Pa_PauseAndFlush(int devHandle);
-
-void Pa_SetLatency( int devHandle, int numBuffers, int framesPerBuffer, int channelsPerFrame )
-{
- int bufferSize;
- audio_info_t solaris_info;
-
- /* Increase size of buffers and reduce number of buffers to reduce latency inside driver. */
- while( numBuffers > 8 )
- {
- numBuffers = (numBuffers + 1) >> 1;
- framesPerBuffer = framesPerBuffer << 1;
- }
-
- /* calculate size of buffers in bytes */
- bufferSize = framesPerBuffer * channelsPerFrame * sizeof(short); /* FIXME - other sizes? */
-
- DBUG(("Pa_SetLatency: numBuffers = %d, framesPerBuffer = %d\n",
- numBuffers, framesPerBuffer));
-
- /* SAM 6/6/02: Documentation says to pause and flush before
- changing buffer size. */
-
- if (Pa_PauseAndFlush(devHandle) != paNoError) {
- ERR_RPT(("Pa_SetLatency: could not pause audio\n" ));
- return;
- }
-
- AUDIO_INITINFO(&solaris_info);
-
- /* AS: Doesn't look like solaris has multiple buffers,
- so I'm being conservative and
- making one buffer. Might not be what we want... */
-
- solaris_info.play.buffer_size = solaris_info.record.buffer_size = bufferSize;
-
- if (ioctl(devHandle, AUDIO_SETINFO, &solaris_info) == -1)
- {
- ERR_RPT(("Pa_SetLatency: could not set audio info\n" ));
- }
- Pa_Unpause(devHandle);
-}
-
-/***********************************************************************/
-PaTimestamp Pa_StreamTime( PortAudioStream *stream )
-{
- internalPortAudioStream *past = (internalPortAudioStream *) stream;
- PaHostSoundControl *pahsc;
- audio_info_t solaris_info;
-
- if( past == NULL ) return paBadStreamPtr;
-
- pahsc = (PaHostSoundControl *) past->past_DeviceData;
-
- ioctl(pahsc->pahsc_OutputHandle, AUDIO_GETINFO, &solaris_info);
- return solaris_info.play.samples;
-}
-
-void Pa_UpdateStreamTime(PaHostSoundControl *pahsc)
-{
- /* AS: Don't need to do anytying for this under Solaris.*/
-}
-
-static PaError Pa_PauseAndFlush(int devHandle)
-{
- audio_info_t solaris_info;
- AUDIO_INITINFO(&solaris_info);
-
- solaris_info.play.pause = solaris_info.record.pause = 1;
-
- if (ioctl(devHandle, AUDIO_SETINFO, &solaris_info) == -1)
- {
- ERR_RPT(("Pa_FlushStream failed.\n"));
- return paHostError;
- }
-
- if (ioctl(devHandle, I_FLUSH, FLUSHRW) == -1)
- {
- ERR_RPT(("Pa_FlushStream failed.\n"));
-
- /* Unpause! */
- AUDIO_INITINFO(&solaris_info);
- solaris_info.play.pause = solaris_info.record.pause = 0;
- ioctl(devHandle, AUDIO_SETINFO, &solaris_info);
-
- return paHostError;
- }
- return paNoError;
-}
-
-static PaError Pa_Unpause(int devHandle)
-{
- audio_info_t solaris_info;
- AUDIO_INITINFO(&solaris_info);
-
- solaris_info.play.pause = solaris_info.record.pause = 0;
-
- if (ioctl(devHandle, AUDIO_SETINFO, &solaris_info) == -1)
- {
- ERR_RPT(("Pa_FlushStream failed.\n"));
- return paHostError;
- }
-
- return paNoError;
-}
-
-PaError Pa_FlushStream(int devHandle)
-{
- PaError res = Pa_PauseAndFlush(devHandle);
- if (res == paNoError)
- return Pa_Unpause(devHandle);
- else return res;
-}
-
-#endif // HAVE_SOLARIS
diff --git a/lib/portaudio/portaudio.h b/lib/portaudio/portaudio.h
deleted file mode 100644
index 38713a6..0000000
--- a/lib/portaudio/portaudio.h
+++ /dev/null
@@ -1,465 +0,0 @@
-#ifndef PORT_AUDIO_H
-#define PORT_AUDIO_H
-
-#include <stdint.h>
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-/*
- * $Id$
- * PortAudio Portable Real-Time Audio Library
- * PortAudio API Header File
- * Latest version available at: http://www.audiomulch.com/portaudio/
- *
- * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files
- * (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * Any person wishing to distribute modifications to the Software is
- * requested to send the modifications to the original developer so that
- * they can be incorporated into the canonical version.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- */
-
-typedef int PaError;
-typedef enum {
- paNoError = 0,
-
- paHostError = -10000,
- paInvalidChannelCount,
- paInvalidSampleRate,
- paInvalidDeviceId,
- paInvalidFlag,
- paSampleFormatNotSupported,
- paBadIODeviceCombination,
- paInsufficientMemory,
- paBufferTooBig,
- paBufferTooSmall,
- paNullCallback,
- paBadStreamPtr,
- paTimedOut,
- paInternalError,
- paDeviceUnavailable
-} PaErrorNum;
-
-/*
- Pa_Initialize() is the library initialisation function - call this before
- using the library.
-
-*/
-
-PaError Pa_Initialize( void );
-
-/*
- Pa_Terminate() is the library termination function - call this after
- using the library.
-
-*/
-
-PaError Pa_Terminate( void );
-
-/*
- Pa_GetHostError() returns a host specific error code.
- This can be called after receiving a PortAudio error code of paHostError.
-
-*/
-
-int32_t Pa_GetHostError( void );
-
-/*
- Pa_GetErrorText() translates the supplied PortAudio error number
- into a human readable message.
-
-*/
-
-const char *Pa_GetErrorText( PaError errnum );
-
-/*
- Sample formats
-
- These are formats used to pass sound data between the callback and the
- stream. Each device has a "native" format which may be used when optimum
- efficiency or control over conversion is required.
-
- Formats marked "always available" are supported (emulated) by all
- PortAudio implementations.
-
- The floating point representation (paFloat32) uses +1.0 and -1.0 as the
- maximum and minimum respectively.
-
- paUInt8 is an unsigned 8 bit format where 128 is considered "ground"
-
-*/
-
-typedef uint32_t PaSampleFormat;
-#define paFloat32 ((PaSampleFormat) (1<<0)) /*always available*/
-#define paInt16 ((PaSampleFormat) (1<<1)) /*always available*/
-#define paInt32 ((PaSampleFormat) (1<<2)) /*always available*/
-#define paInt24 ((PaSampleFormat) (1<<3))
-#define paPackedInt24 ((PaSampleFormat) (1<<4))
-#define paInt8 ((PaSampleFormat) (1<<5))
-#define paUInt8 ((PaSampleFormat) (1<<6))
-#define paCustomFormat ((PaSampleFormat) (1<<16))
-
-/*
- Device enumeration mechanism.
-
- Device ids range from 0 to Pa_CountDevices()-1.
-
- Devices may support input, output or both.
-
-*/
-
-typedef int PaDeviceID;
-#define paNoDevice -1
-
-int Pa_CountDevices( void );
-
-typedef struct
-{
- int structVersion;
- const char *name;
- int maxInputChannels;
- int maxOutputChannels;
- /* Number of discrete rates, or -1 if range supported. */
- int numSampleRates;
- /* Array of supported sample rates, or {min,max} if range supported. */
- const double *sampleRates;
- PaSampleFormat nativeSampleFormats;
-}
-PaDeviceInfo;
-
-/*
- Pa_GetDefaultInputDeviceID(), Pa_GetDefaultOutputDeviceID() return the
- default device ids for input and output respectively, or paNoDevice if
- no device is available.
- The result can be passed to Pa_OpenStream().
-
- On the PC, the user can specify a default device by
- setting an environment variable. For example, to use device #1.
-
- set PA_RECOMMENDED_OUTPUT_DEVICE=1
-
- The user should first determine the available device ids by using
- the supplied application "pa_devs".
-
-*/
-
-PaDeviceID Pa_GetDefaultInputDeviceID( void );
-PaDeviceID Pa_GetDefaultOutputDeviceID( void );
-
-
-
-/*
- Pa_GetDeviceInfo() returns a pointer to an immutable PaDeviceInfo structure
- for the device specified.
- If the device parameter is out of range the function returns NULL.
-
- PortAudio manages the memory referenced by the returned pointer, the client
- must not manipulate or free the memory. The pointer is only guaranteed to be
- valid between calls to Pa_Initialize() and Pa_Terminate().
-
-*/
-
-const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceID device );
-
-/*
- PaTimestamp is used to represent a continuous sample clock with arbitrary
- start time that can be used for syncronization. The type is used for the
- outTime argument to the PortAudioCallback and as the result of Pa_StreamTime()
-
-*/
-
-typedef double PaTimestamp;
-
-/*
- PortAudioCallback is implemented by PortAudio clients.
-
- inputBuffer and outputBuffer are arrays of interleaved samples,
- the format, packing and number of channels used by the buffers are
- determined by parameters to Pa_OpenStream() (see below).
-
- framesPerBuffer is the number of sample frames to be processed by the callback.
-
- outTime is the time in samples when the buffer(s) processed by
- this callback will begin being played at the audio output.
- See also Pa_StreamTime()
-
- userData is the value of a user supplied pointer passed to Pa_OpenStream()
- intended for storing synthesis data etc.
-
- return value:
- The callback can return a non-zero value to stop the stream. This may be
- useful in applications such as soundfile players where a specific duration
- of output is required. However, it is not necessary to utilise this mechanism
- as StopStream() will also terminate the stream. A callback returning a
- non-zero value must fill the entire outputBuffer.
-
- NOTE: None of the other stream functions may be called from within the
- callback function except for Pa_GetCPULoad().
-
-*/
-
-typedef int (PortAudioCallback)(
- void *inputBuffer, void *outputBuffer,
- uint32_t framesPerBuffer,
- PaTimestamp outTime, void *userData );
-
-
-/*
- Stream flags
-
- These flags may be supplied (ored together) in the streamFlags argument to
- the Pa_OpenStream() function.
-
-*/
-
-#define paNoFlag (0)
-#define paClipOff (1<<0) /* disable default clipping of out of range samples */
-#define paDitherOff (1<<1) /* disable default dithering */
-#define paPlatformSpecificFlags (0x00010000)
-typedef uint32_t PaStreamFlags;
-
-/*
- A single PortAudioStream provides multiple channels of real-time
- input and output audio streaming to a client application.
- Pointers to PortAudioStream objects are passed between PortAudio functions.
-*/
-
-typedef void PortAudioStream;
-#define PaStream PortAudioStream
-
-/*
- Pa_OpenStream() opens a stream for either input, output or both.
-
- stream is the address of a PortAudioStream pointer which will receive
- a pointer to the newly opened stream.
-
- inputDevice is the id of the device used for input (see PaDeviceID above.)
- inputDevice may be paNoDevice to indicate that an input device is not required.
-
- numInputChannels is the number of channels of sound to be delivered to the
- callback. It can range from 1 to the value of maxInputChannels in the
- PaDeviceInfo record for the device specified by the inputDevice parameter.
- If inputDevice is paNoDevice numInputChannels is ignored.
-
- inputSampleFormat is the sample format of inputBuffer provided to the callback
- function. inputSampleFormat may be any of the formats described by the
- PaSampleFormat enumeration (see above). PortAudio guarantees support for
- the device's native formats (nativeSampleFormats in the device info record)
- and additionally 16 and 32 bit integer and 32 bit floating point formats.
- Support for other formats is implementation defined.
-
- inputDriverInfo is a pointer to an optional driver specific data structure
- containing additional information for device setup or stream processing.
- inputDriverInfo is never required for correct operation. If not used
- inputDriverInfo should be NULL.
-
- outputDevice is the id of the device used for output (see PaDeviceID above.)
- outputDevice may be paNoDevice to indicate that an output device is not required.
-
- numOutputChannels is the number of channels of sound to be supplied by the
- callback. See the definition of numInputChannels above for more details.
-
- outputSampleFormat is the sample format of the outputBuffer filled by the
- callback function. See the definition of inputSampleFormat above for more
- details.
-
- outputDriverInfo is a pointer to an optional driver specific data structure
- containing additional information for device setup or stream processing.
- outputDriverInfo is never required for correct operation. If not used
- outputDriverInfo should be NULL.
-
- sampleRate is the desired sampleRate. For full-duplex streams it is the
- sample rate for both input and output
-
- framesPerBuffer is the length in sample frames of all internal sample buffers
- used for communication with platform specific audio routines. Wherever
- possible this corresponds to the framesPerBuffer parameter passed to the
- callback function.
-
- numberOfBuffers is the number of buffers used for multibuffered communication
- with the platform specific audio routines. If you pass zero, then an optimum
- value will be chosen for you internally. This parameter is provided only
- as a guide - and does not imply that an implementation must use multibuffered
- i/o when reliable double buffering is available (such as SndPlayDoubleBuffer()
- on the Macintosh.)
-
- streamFlags may contain a combination of flags ORed together.
- These flags modify the behaviour of the streaming process. Some flags may only
- be relevant to certain buffer formats.
-
- callback is a pointer to a client supplied function that is responsible
- for processing and filling input and output buffers (see above for details.)
-
- userData is a client supplied pointer which is passed to the callback
- function. It could for example, contain a pointer to instance data necessary
- for processing the audio buffers.
-
- return value:
- Upon success Pa_OpenStream() returns PaNoError and places a pointer to a
- valid PortAudioStream in the stream argument. The stream is inactive (stopped).
- If a call to Pa_OpenStream() fails a non-zero error code is returned (see
- PaError above) and the value of stream is invalid.
-
-*/
-
-PaError Pa_OpenStream( PortAudioStream** stream,
- PaDeviceID inputDevice,
- int numInputChannels,
- PaSampleFormat inputSampleFormat,
- void *inputDriverInfo,
- PaDeviceID outputDevice,
- int numOutputChannels,
- PaSampleFormat outputSampleFormat,
- void *outputDriverInfo,
- double sampleRate,
- uint32_t framesPerBuffer,
- uint32_t numberOfBuffers,
- PaStreamFlags streamFlags,
- PortAudioCallback *callback,
- void *userData );
-
-
-/*
- Pa_OpenDefaultStream() is a simplified version of Pa_OpenStream() that opens
- the default input and/or output devices. Most parameters have identical meaning
- to their Pa_OpenStream() counterparts, with the following exceptions:
-
- If either numInputChannels or numOutputChannels is 0 the respective device
- is not opened. This has the same effect as passing paNoDevice in the device
- arguments to Pa_OpenStream().
-
- sampleFormat applies to both the input and output buffers.
-
-*/
-
-PaError Pa_OpenDefaultStream( PortAudioStream** stream,
- int numInputChannels,
- int numOutputChannels,
- PaSampleFormat sampleFormat,
- double sampleRate,
- uint32_t framesPerBuffer,
- uint32_t numberOfBuffers,
- PortAudioCallback *callback,
- void *userData );
-
-/*
- Pa_CloseStream() closes an audio stream, flushing any pending buffers.
-
-*/
-
-PaError Pa_CloseStream( PortAudioStream* );
-
-/*
- Pa_StartStream() and Pa_StopStream() begin and terminate audio processing.
- Pa_StopStream() waits until all pending audio buffers have been played.
- Pa_AbortStream() stops playing immediately without waiting for pending
- buffers to complete.
-
-*/
-
-PaError Pa_StartStream( PortAudioStream *stream );
-
-PaError Pa_StopStream( PortAudioStream *stream );
-
-PaError Pa_AbortStream( PortAudioStream *stream );
-
-/*
- Pa_StreamActive() returns one (1) when the stream is active (ie playing
- or recording audio), zero (0) when not playing, or a negative error number
- if the stream is invalid.
- The stream is active between calls to Pa_StartStream() and Pa_StopStream(),
- but may also become inactive if the callback returns a non-zero value.
- In the latter case, the stream is considered inactive after the last
- buffer has finished playing.
-
-*/
-
-PaError Pa_StreamActive( PortAudioStream *stream );
-
-/*
- Pa_StreamTime() returns the current output time in samples for the stream.
- This time may be used as a time reference (for example synchronizing audio to
- MIDI).
-
-*/
-
-PaTimestamp Pa_StreamTime( PortAudioStream *stream );
-
-/*
- Pa_GetCPULoad() returns the CPU Load for the stream.
- The "CPU Load" is a fraction of total CPU time consumed by the stream's
- audio processing routines including, but not limited to the client supplied
- callback.
- A value of 0.5 would imply that PortAudio and the sound generating
- callback was consuming roughly 50% of the available CPU time.
- This function may be called from the callback function or the application.
-
-*/
-
-double Pa_GetCPULoad( PortAudioStream* stream );
-
-/*
- Pa_GetMinNumBuffers() returns the minimum number of buffers required by
- the current host based on minimum latency.
- On the PC, for the DirectSound implementation, latency can be optionally set
- by user by setting an environment variable.
- For example, to set latency to 200 msec, put:
-
- set PA_MIN_LATENCY_MSEC=200
-
- in the AUTOEXEC.BAT file and reboot.
- If the environment variable is not set, then the latency will be determined
- based on the OS. Windows NT has higher latency than Win95.
-
-*/
-
-int Pa_GetMinNumBuffers( int framesPerBuffer, double sampleRate );
-
-/*
- Pa_Sleep() puts the caller to sleep for at least 'msec' milliseconds.
- You may sleep longer than the requested time so don't rely on this for
- accurate musical timing.
-
- Pa_Sleep() is provided as a convenience for authors of portable code (such as
- the tests and examples in the PortAudio distribution.)
-
-*/
-
-void Pa_Sleep( int32_t msec );
-
-/*
- Pa_GetSampleSize() returns the size in bytes of a single sample in the
- supplied PaSampleFormat, or paSampleFormatNotSupported if the format is
- no supported.
-
-*/
-
-PaError Pa_GetSampleSize( PaSampleFormat format );
-
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-#endif /* PORT_AUDIO_H */
diff --git a/lib/portaudio/ringbuffer.c b/lib/portaudio/ringbuffer.c
deleted file mode 100644
index 1c893b2..0000000
--- a/lib/portaudio/ringbuffer.c
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * $Id$
- * ringbuffer.c
- * Ring Buffer utility..
- *
- * Author: Phil Burk, http://www.softsynth.com
- *
- * This program uses the PortAudio Portable Audio Library.
- * For more information see: http://www.audiomulch.com/portaudio/
- * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files
- * (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * Any person wishing to distribute modifications to the Software is
- * requested to send the modifications to the original developer so that
- * they can be incorporated into the canonical version.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include <math.h>
-#include "ringbuffer.h"
-#include <string.h>
-
-/***************************************************************************
- * Initialize FIFO.
- * numBytes must be power of 2, returns -1 if not.
- */
-int32_t RingBuffer_Init( RingBuffer *rbuf, int32_t numBytes, void *dataPtr )
-{
- if( ((numBytes-1) & numBytes) != 0) return -1; /* Not Power of two. */
- rbuf->bufferSize = numBytes;
- rbuf->buffer = (char *)dataPtr;
- RingBuffer_Flush( rbuf );
- rbuf->bigMask = (numBytes*2)-1;
- rbuf->smallMask = (numBytes)-1;
- return 0;
-}
-/***************************************************************************
-** Return number of bytes available for reading. */
-int32_t RingBuffer_GetReadAvailable( RingBuffer *rbuf )
-{
- return ( (rbuf->writeIndex - rbuf->readIndex) & rbuf->bigMask );
-}
-/***************************************************************************
-** Return number of bytes available for writing. */
-int32_t RingBuffer_GetWriteAvailable( RingBuffer *rbuf )
-{
- return ( rbuf->bufferSize - RingBuffer_GetReadAvailable(rbuf));
-}
-
-/***************************************************************************
-** Clear buffer. Should only be called when buffer is NOT being read. */
-void RingBuffer_Flush( RingBuffer *rbuf )
-{
- rbuf->writeIndex = rbuf->readIndex = 0;
-}
-
-/***************************************************************************
-** Get address of region(s) to which we can write data.
-** If the region is contiguous, size2 will be zero.
-** If non-contiguous, size2 will be the size of second region.
-** Returns room available to be written or numBytes, whichever is smaller.
-*/
-int32_t RingBuffer_GetWriteRegions( RingBuffer *rbuf, int32_t numBytes,
- void **dataPtr1, int32_t *sizePtr1,
- void **dataPtr2, int32_t *sizePtr2 )
-{
- int32_t index;
- int32_t available = RingBuffer_GetWriteAvailable( rbuf );
- if( numBytes > available ) numBytes = available;
- /* Check to see if write is not contiguous. */
- index = rbuf->writeIndex & rbuf->smallMask;
- if( (index + numBytes) > rbuf->bufferSize )
- {
- /* Write data in two blocks that wrap the buffer. */
- int32_t firstHalf = rbuf->bufferSize - index;
- *dataPtr1 = &rbuf->buffer[index];
- *sizePtr1 = firstHalf;
- *dataPtr2 = &rbuf->buffer[0];
- *sizePtr2 = numBytes - firstHalf;
- }
- else
- {
- *dataPtr1 = &rbuf->buffer[index];
- *sizePtr1 = numBytes;
- *dataPtr2 = NULL;
- *sizePtr2 = 0;
- }
- return numBytes;
-}
-
-
-/***************************************************************************
-*/
-int32_t RingBuffer_AdvanceWriteIndex( RingBuffer *rbuf, int32_t numBytes )
-{
- return rbuf->writeIndex = (rbuf->writeIndex + numBytes) & rbuf->bigMask;
-}
-
-/***************************************************************************
-** Get address of region(s) from which we can read data.
-** If the region is contiguous, size2 will be zero.
-** If non-contiguous, size2 will be the size of second region.
-** Returns room available to be written or numBytes, whichever is smaller.
-*/
-int32_t RingBuffer_GetReadRegions( RingBuffer *rbuf, int32_t numBytes,
- void **dataPtr1, int32_t *sizePtr1,
- void **dataPtr2, int32_t *sizePtr2 )
-{
- int32_t index;
- int32_t available = RingBuffer_GetReadAvailable( rbuf );
- if( numBytes > available ) numBytes = available;
- /* Check to see if read is not contiguous. */
- index = rbuf->readIndex & rbuf->smallMask;
- if( (index + numBytes) > rbuf->bufferSize )
- {
- /* Write data in two blocks that wrap the buffer. */
- int32_t firstHalf = rbuf->bufferSize - index;
- *dataPtr1 = &rbuf->buffer[index];
- *sizePtr1 = firstHalf;
- *dataPtr2 = &rbuf->buffer[0];
- *sizePtr2 = numBytes - firstHalf;
- }
- else
- {
- *dataPtr1 = &rbuf->buffer[index];
- *sizePtr1 = numBytes;
- *dataPtr2 = NULL;
- *sizePtr2 = 0;
- }
- return numBytes;
-}
-/***************************************************************************
-*/
-int32_t RingBuffer_AdvanceReadIndex( RingBuffer *rbuf, int32_t numBytes )
-{
- return rbuf->readIndex = (rbuf->readIndex + numBytes) & rbuf->bigMask;
-}
-
-/***************************************************************************
-** Return bytes written. */
-int32_t RingBuffer_Write( RingBuffer *rbuf, void *data, int32_t numBytes )
-{
- int32_t size1, size2, numWritten;
- void *data1, *data2;
- numWritten = RingBuffer_GetWriteRegions( rbuf, numBytes, &data1, &size1, &data2, &size2 );
- if( size2 > 0 )
- {
-
- memcpy( data1, data, size1 );
- data = ((char *)data) + size1;
- memcpy( data2, data, size2 );
- }
- else
- {
- memcpy( data1, data, size1 );
- }
- RingBuffer_AdvanceWriteIndex( rbuf, numWritten );
- return numWritten;
-}
-
-/***************************************************************************
-** Return bytes read. */
-int32_t RingBuffer_Read( RingBuffer *rbuf, void *data, int32_t numBytes )
-{
- int32_t size1, size2, numRead;
- void *data1, *data2;
- numRead = RingBuffer_GetReadRegions( rbuf, numBytes, &data1, &size1, &data2, &size2 );
- if( size2 > 0 )
- {
- memcpy( data, data1, size1 );
- data = ((char *)data) + size1;
- memcpy( data, data2, size2 );
- }
- else
- {
- memcpy( data, data1, size1 );
- }
- RingBuffer_AdvanceReadIndex( rbuf, numRead );
- return numRead;
-}
diff --git a/lib/portaudio/ringbuffer.h b/lib/portaudio/ringbuffer.h
deleted file mode 100644
index 88e665c..0000000
--- a/lib/portaudio/ringbuffer.h
+++ /dev/null
@@ -1,102 +0,0 @@
-#ifndef _RINGBUFFER_H
-#define _RINGBUFFER_H
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-/*
- * $Id$
- * ringbuffer.h
- * Ring Buffer utility..
- *
- * Author: Phil Burk, http://www.softsynth.com
- *
- * This program is distributed with the PortAudio Portable Audio Library.
- * For more information see: http://www.audiomulch.com/portaudio/
- * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files
- * (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * Any person wishing to distribute modifications to the Software is
- * requested to send the modifications to the original developer so that
- * they can be incorporated into the canonical version.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include <math.h>
-#include "ringbuffer.h"
-#include <string.h>
-
-typedef struct
-{
- int32_t bufferSize; /* Number of bytes in FIFO. Power of 2. Set by RingBuffer_Init. */
-/* These are declared volatile because they are written by a different thread than the reader. */
- volatile int32_t writeIndex; /* Index of next writable byte. Set by RingBuffer_AdvanceWriteIndex. */
- volatile int32_t readIndex; /* Index of next readable byte. Set by RingBuffer_AdvanceReadIndex. */
- int32_t bigMask; /* Used for wrapping indices with extra bit to distinguish full/empty. */
- int32_t smallMask; /* Used for fitting indices to buffer. */
- char *buffer;
-}
-RingBuffer;
-/*
- * Initialize Ring Buffer.
- * numBytes must be power of 2, returns -1 if not.
- */
-int32_t RingBuffer_Init( RingBuffer *rbuf, int32_t numBytes, void *dataPtr );
-
-/* Clear buffer. Should only be called when buffer is NOT being read. */
-void RingBuffer_Flush( RingBuffer *rbuf );
-
-/* Return number of bytes available for writing. */
-int32_t RingBuffer_GetWriteAvailable( RingBuffer *rbuf );
-/* Return number of bytes available for read. */
-int32_t RingBuffer_GetReadAvailable( RingBuffer *rbuf );
-/* Return bytes written. */
-int32_t RingBuffer_Write( RingBuffer *rbuf, void *data, int32_t numBytes );
-/* Return bytes read. */
-int32_t RingBuffer_Read( RingBuffer *rbuf, void *data, int32_t numBytes );
-
-/* Get address of region(s) to which we can write data.
-** If the region is contiguous, size2 will be zero.
-** If non-contiguous, size2 will be the size of second region.
-** Returns room available to be written or numBytes, whichever is smaller.
-*/
-int32_t RingBuffer_GetWriteRegions( RingBuffer *rbuf, int32_t numBytes,
- void **dataPtr1, int32_t *sizePtr1,
- void **dataPtr2, int32_t *sizePtr2 );
-int32_t RingBuffer_AdvanceWriteIndex( RingBuffer *rbuf, int32_t numBytes );
-
-/* Get address of region(s) from which we can read data.
-** If the region is contiguous, size2 will be zero.
-** If non-contiguous, size2 will be the size of second region.
-** Returns room available to be read or numBytes, whichever is smaller.
-*/
-int32_t RingBuffer_GetReadRegions( RingBuffer *rbuf, int32_t numBytes,
- void **dataPtr1, int32_t *sizePtr1,
- void **dataPtr2, int32_t *sizePtr2 );
-
-int32_t RingBuffer_AdvanceReadIndex( RingBuffer *rbuf, int32_t numBytes );
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-#endif /* _RINGBUFFER_H */
diff --git a/src/dev_sound.h b/src/dev_sound.h
index cd4d718..5efe638 100644
--- a/src/dev_sound.h
+++ b/src/dev_sound.h
@@ -7,9 +7,7 @@
#include <jack/jack.h>
#endif
-//#ifdef HAVE_PORTAUDIO
#include <portaudio.h>
-//#endif
#include <pipe.h>