]> Repos - portaudio/commitdiff
moved pateam to tags/unknown-was-pateam and added a README.txt for the folder. unknown-was-pateam
authorbjornroche <bjornroche@0f58301d-fd10-0410-b4af-bbb618454e57>
Thu, 20 Mar 2008 14:14:19 +0000 (14:14 +0000)
committerbjornroche <bjornroche@0f58301d-fd10-0410-b4af-bbb618454e57>
Thu, 20 Mar 2008 14:14:19 +0000 (14:14 +0000)
82 files changed:
LICENSE.txt [deleted file]
Makefile.in [deleted file]
Makefile.linux
Makefile.mingw [deleted file]
README.txt
config.guess [deleted file]
config.sub [deleted file]
configure [deleted file]
configure.in [deleted file]
docs/index.html [deleted file]
docs/latency.html [deleted file]
docs/pa_impl_guide.html [deleted file]
docs/pa_impl_startstop.html [deleted file]
docs/pa_tut_asio.html [deleted file]
docs/pa_tut_callback.html [deleted file]
docs/pa_tut_devs.html [deleted file]
docs/pa_tut_explore.html [deleted file]
docs/pa_tut_init.html [deleted file]
docs/pa_tut_mac.html [deleted file]
docs/pa_tut_mac_osx.html [deleted file]
docs/pa_tut_open.html [deleted file]
docs/pa_tut_oss.html [deleted file]
docs/pa_tut_over.html [deleted file]
docs/pa_tut_pc.html [deleted file]
docs/pa_tut_run.html [deleted file]
docs/pa_tut_rw.html [deleted file]
docs/pa_tut_term.html [deleted file]
docs/pa_tut_util.html [deleted file]
docs/pa_tutorial.html [deleted file]
docs/portaudio_h.txt [deleted file]
docs/portaudio_icmc2001.pdf [deleted file]
docs/proposals.html [deleted file]
docs/releases.html [deleted file]
docs/style.html [deleted file]
fixfile.bat [deleted file]
index.html [deleted file]
install-sh [deleted file]
pa_asio/borland_asio_readme.txt [deleted file]
pa_asio/pa_asio.cpp
pa_asio/readme_asio_sdk_patch.txt [deleted file]
pa_common/pa_convert.c [deleted file]
pa_common/pa_host.h
pa_common/pa_lib.c
pa_common/portaudio.h
pa_mac/pa_mac.c
pa_mac_core/notes.txt [deleted file]
pa_mac_core/pa_mac_core.c
pa_sgi/Makefile
pa_sgi/pa_sgi.c
pa_sgi/pthread-Makefile [deleted file]
pa_sgi/pthread-pa_sgi.c [deleted file]
pa_tests/debug_convert.c [deleted file]
pa_tests/debug_dither_calc.c [deleted file]
pa_tests/debug_multi_out.c
pa_tests/debug_record.c
pa_tests/debug_record_reuse.c [deleted file]
pa_tests/debug_sine.c
pa_tests/debug_sine_amp.c [deleted file]
pa_tests/debug_sine_formats.c [deleted file]
pa_tests/debug_sine_wait.c [moved from pa_tests/patest_hang.c with 76% similarity]
pa_tests/debug_srate.c [deleted file]
pa_tests/pa_minlat.c
pa_tests/paqa_errs.c
pa_tests/patest_dither.c
pa_tests/patest_latency.c
pa_tests/patest_leftright.c
pa_tests/patest_longsine.c
pa_tests/patest_maxsines.c
pa_tests/patest_multi_sine.c [deleted file]
pa_tests/patest_record.c
pa_tests/patest_sine.c
pa_tests/patest_sine_formats.c
pa_tests/patest_sine_time.c
pa_tests/patest_toomanysines.c [deleted file]
pa_tests/patest_wire.c
pa_unix_oss/Makefile
pa_unix_oss/pa_unix_oss.c
pa_win_ds/pa_dsound.c
pa_win_wmme/pa_win_wmme.c
pablio/test_rw.c
testcvs/changeme.txt [deleted file]
testcvs/stuff/info.txt [deleted file]

diff --git a/LICENSE.txt b/LICENSE.txt
deleted file mode 100644 (file)
index 105da3f..0000000
+++ /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/Makefile.in b/Makefile.in
deleted file mode 100644 (file)
index 2a3cc34..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-#
-# PortAudio Makefile.in
-#
-# Dominic Mazzoni
-#
-
-PREFIX = @prefix@
-CC = @CC@
-CFLAGS = @CFLAGS@ -Ipa_common
-LIBS = @LIBS@
-AR = @AR@
-RANLIB = @RANLIB@
-INSTALL = @INSTALL@
-SHARED_FLAGS = @SHARED_FLAGS@
-DLL_LIBS = @DLL_LIBS@
-
-OTHER_OBJS = @OTHER_OBJS@
-
-PALIB = libportaudio.a
-PADLL = @PADLL@
-PADLLV = $(PADLL).0.0.18
-PAINC = pa_common/portaudio.h
-
-COMMON_OBJS = \
-       pa_common/pa_convert.o \
-       pa_common/pa_lib.o
-
-TESTS = \
-       bin/patest_buffer \
-       bin/patest_clip \
-       bin/patest_dither \
-       bin/patest_hang \
-       bin/patest_latency \
-       bin/patest_leftright \
-       bin/patest_longsine \
-       bin/patest_many \
-       bin/patest_maxsines \
-       bin/patest_multi_sine \
-       bin/patest_pink \
-       bin/patest_record \
-       bin/patest_ringmix \
-       bin/patest_saw \
-       bin/patest_sine8 \
-       bin/patest_sine \
-       bin/patest_sine_formats \
-       bin/patest_sine_time \
-       bin/patest_stop \
-       bin/patest_sync \
-       bin/patest_toomanysines \
-       bin/patest_underflow \
-       bin/patest_wire
-
-OBJS = $(COMMON_OBJS) $(OTHER_OBJS)
-
-all: lib/$(PALIB) lib/$(PADLLV) tests
-
-tests: bin/ $(TESTS)
-
-lib/$(PALIB): lib/ $(OBJS) Makefile $(PAINC)
-       $(AR) ruv lib/$(PALIB) $(OBJS)
-       $(RANLIB) lib/$(PALIB)
-
-lib/$(PADLLV): lib/ $(OBJS) Makefile $(PAINC)
-       $(CC) $(SHARED_FLAGS) -o lib/$(PADLLV) $(OBJS) $(DLL_LIBS)
-
-$(TESTS): bin/%: lib/$(PALIB) Makefile $(PAINC) pa_tests/%.c
-       $(CC) -o $@ $(CFLAGS) pa_tests/$*.c lib/$(PALIB) $(LIBS)
-
-install: lib/$(PALIB) lib/$(PADLLV)
-       $(INSTALL) -m 644 lib/$(PADLLV) $(PREFIX)/lib/$(PADLLV)
-       $(INSTALL) -m 644 lib/$(PALIB) $(PREFIX)/lib/$(PALIB)
-       cd $(PREFIX)/lib && rm -f $(PADLL) && ln -s $(PADLLV) $(PADLL)
-       $(INSTALL) -m 644 pa_common/portaudio.h $(PREFIX)/include/portaudio.h
-       @echo ""
-       @echo "------------------------------------------------------------"
-       @echo "PortAudio was successfully installed."
-       @echo ""
-       @echo "On some systems (e.g. Linux) you should run 'ldconfig' now"
-       @echo "to make the shared object available.  You may also need to"
-       @echo "modify your LD_LIBRARY_PATH environment variable to include"
-       @echo "the directory $(PREFIX)/lib"
-       @echo "------------------------------------------------------------"
-       @echo ""
-
-clean:
-       rm -f $(OBJS) $(TESTS) lib/$(PALIB)
-
-%.o: %.c Makefile $(PAINC)
-       $(CC) -c $(CFLAGS) $< -o $@
-
-bin:
-       mkdir bin
-
-lib:
-       mkdir lib
index 4deee60ac4ffb6070ecf624a18761f633d49a4df..9f67ce6acc2ba80f6b870deaa9283b12514fca1f 100644 (file)
@@ -1,8 +1,6 @@
 # Make PortAudio for Linux
 # Updated 2001/08/25 Bill Eldridge bill@rfa.org
 # Updated 2001/10/16, philburk@softsynth.com, s/unix_oss/unix_oss/
-# Updated 2002/04/30 Bill Eldridge bill@rfa.org
-#     Made the libinstall and tests compile a bit cleaner
 
 # A pretty bare makefile, that figures out all the test files
 # and compiles them against the library in the pa_unix_oss directory.
@@ -21,34 +19,23 @@ CFLAGS = -g
 LIBINST = /usr/local/lib
 
 TESTS:= $(wildcard pa_tests/pa*.c pa_tests/debug*.c)
-TESTO:= $(wildcard pa_tests/pa*.o pa_tests/debug*.o)
 
 LIBFILES:= ./pa_common/pa_lib.c ./pa_unix_oss/pa_unix_oss.c
 
-#all: sharedlib libinstall tests
-all: sharedlib libinstall testo testq
-
 .c.o:
        -gcc -c -I./pa_common $< -o $*.o
-
-.o:
        -gcc $*.o -o $* -Lpa_unix_oss $(LIBS) -lportaudio
 
-#.c.o:
-#      -gcc -c -I./pa_common $< -o $*.o
-#      -gcc $*.o -o $* -Lpa_unix_oss $(LIBS) -lportaudio
-
+all: sharedlib tests
 
 sharedlib:     $(LIBFILES:.c=.o)
        gcc -shared -o ./pa_unix_oss/libportaudio.so ./pa_common/pa_lib.o ./pa_unix_oss/pa_unix_oss.o
 
 libinstall:    ./pa_unix_oss/libportaudio.so
        @cp -f ./pa_unix_oss/libportaudio.so $(LIBINST)
-       @/sbin/ldconfig
-
-testo: $(TESTS:.c=.o)
+       @/sbin/ldconfig -v
 
-testq: $(TESTO:.o=)
+tests: $(TESTS:.c=.o)
 
 clean:
        -@rm -f $(TESTS:.c=.o)
diff --git a/Makefile.mingw b/Makefile.mingw
deleted file mode 100644 (file)
index 2043a16..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-
-# Makefile for PortAudio on mingw (http://mingw.sourceforge.net)
-
-# Contributed by Bill Eldridge, bill@rfa.org, Radio Free Asia
-# Copyright 2002/02/20, GPL
-
-# Uses a common mingw32 cross-compiler that defaults
-# to everything in /usr/local/cross-tools
-
-# First edit your path with 
-# export PATH=/usr/local/cross-tools/bin:$PATH
-
-# Usage: make -f Makefile.mingw all
-# or     make -f Makefile.mingw sharedlib
-#        make -f Makefile.mingw tests
-#
-# Then copy executables & portaudio.dll to your Windows machine
-#
-# To make work with pa_win_ds, you'll have to substitue
-# all the pa_win_wmme files with pa_win_ds files, no biggie.
-
-CC= i586-mingw32msvc-gcc
-DLLTOOL= i586-mingw32msvc-dlltool
-DLLWRAP= i586-mingw32msvc-dllwrap
-
-ARCH= pa_win_wmme
-
-TESTS:= $(wildcard pa_tests/pa*.c pa_tests/debug*.c)
-
-.c.o:
-       -$(CC) -c -I./pa_common $< -o $*.o
-       -$(CC) $*.o -o $*.exe -L/usr/local/lib -L$(ARCH) -lportaudio.dll -lwinmm
-
-all:   sharedlib tests
-
-sharedlib: ./pa_common/pa_lib.c 
-       $(CC) -c -I./pa_common pa_common/pa_lib.c -o pa_common/pa_lib.o
-       $(CC) -c -I./pa_common pa_win_wmme/pa_win_wmme.c -o pa_win_wmme/pa_win_wmme.o
-       $(CC) -shared -mthreads -o portaudio.dll pa_common/pa_lib.o pa_win_wmme/pa_win_wmme.o -L/usr/local/cross-tools/i586-win32msvc/lib -lwinmm -lm
-       $(DLLWRAP) --export-all --output-def=libportaudio.def --output-lib=libportaudio.a --dllname=portaudio.dll --drivername=i586-mingw32msvc-gcc  pa_common/pa_lib.o pa_win_wmme/pa_win_wmme.o -L/usr/local/cross-tools/i586-win32msvc/lib -lwinmm -lm
-       $(CC) -shared -Wl,--enable-auto-image-base -o portaudio.dll -Wl,--out-implib=pa_win_wmme/libportaudio.dll.a pa_common/pa_lib.o pa_win_wmme/pa_win_wmme.o -L/usr/local/cross-tools/i586-win32msvc/lib -lwinmm
-
-
-tests: $(TESTS:.c=.o)
-
-sine:
-       $(CC) -c -I./pa_common pa_tests/patest_sine.c -o pa_tests/patest_sine.o
-       $(CC) pa_tests/patest_sine.o -o pa_tests/patest_sine.exe -L/usr/local/lib -lportaudio.dll -lwinmm
-
-clean:
-       -rm ./pa_tests/*.exe
-       -rm ./pa_tests/*.o
-       
-nothing:
-       $(CC) pa_tests/patest_sine.o -L/usr/lib/w32api -L./pa_win_wmme -lportaudio.dll -lwinmm
-
-       
index d1e5d7d6ef05cf61a4c003d67506c8c35c5a48c1..71259313539027805ec53e2cd0350b1e6fa961db 100644 (file)
@@ -1,81 +1 @@
-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
+This folder may have had something to do with the original CVS import. No one else on the mailing list knew what it was either, but it was decided that we aught to keep it in tags, rather than branges, where it was originally. It was originally called "pateam" and before I touched it it was last touched by "anonymous" in 2002ish. -Bjorn Roche
diff --git a/config.guess b/config.guess
deleted file mode 100755 (executable)
index 297e5c3..0000000
Binary files a/config.guess and /dev/null differ
diff --git a/config.sub b/config.sub
deleted file mode 100755 (executable)
index 791bcde..0000000
Binary files a/config.sub and /dev/null differ
diff --git a/configure b/configure
deleted file mode 100755 (executable)
index 105c7ed..0000000
Binary files a/configure and /dev/null differ
diff --git a/configure.in b/configure.in
deleted file mode 100644 (file)
index f5b31a0..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-dnl
-dnl PortAudio configure.in script
-dnl
-dnl Dominic Mazzoni
-dnl
-
-dnl Require autoconf >= 2.13
-AC_PREREQ(2.13)
-
-dnl Init autoconf and make sure configure is being called
-dnl from the right directory
-AC_INIT([pa_common/portaudio.h])
-
-dnl Checks for programs
-AC_PROG_CC
-AC_PROG_RANLIB
-AC_PROG_INSTALL
-AC_PATH_PROG(AR, ar, no)
-if [[ $AR = "no" ]] ; then
-   AC_MSG_ERROR("Could not find ar - needed to create a library");
-fi
-
-dnl Extra variables we want to substitute
-AC_SUBST(OTHER_OBJS)
-AC_SUBST(PADLL)
-AC_SUBST(SHARED_FLAGS)
-AC_SUBST(DLL_LIBS)
-
-dnl Determine the host operating system / platform
-AC_CANONICAL_HOST
-
-case "${host_os}" in
-  darwin* )
-       dnl Mac OS X configuration
-
-       OTHER_OBJS="pa_mac_core/pa_mac_core.o";
-       LIBS="-framework CoreAudio -lm";
-       PADLL="libportaudio.dylib";
-       SHARED_FLAGS="-framework CoreAudio -dynamiclib";
-       ;;
-
-  mingw* )
-       dnl MingW configuration
-
-       OTHER_OBJS="pa_win_wmme/pa_win_wmme.o";
-       LIBS="-lwinmm -lm";
-       PADLL="portaudio.dll";
-       SHARED_FLAGS="-shared -mthreads";
-       DLL_LIBS="-lwinmm";
-       ;;
-
-  cygwin* )
-       dnl Cygwin configuration
-
-       OTHER_OBJS="pa_win_wmme/pa_win_wmme.o";
-       LIBS="-lwinmm -lm";
-       PADLL="portaudio.dll";
-       SHARED_FLAGS="-shared -mthreads";
-       DLL_LIBS="-lwinmm";
-       ;;
-
-  *)
-       dnl Unix OSS configuration
-
-   AC_CHECK_LIB(pthread, pthread_create,
-                ,
-                AC_MSG_ERROR([libpthread not found!]))
-
-       OTHER_OBJS="pa_unix_oss/pa_unix_oss.o";
-       LIBS="-lm -lpthread";
-       PADLL="libportaudio.so";
-       SHARED_FLAGS="-shared";
-esac
-
-AC_OUTPUT([Makefile])
-
-echo ""
-echo "Finished configure."
-
-echo ""
-echo "Type 'make' to build PortAudio and examples."
diff --git a/docs/index.html b/docs/index.html
deleted file mode 100644 (file)
index dfd648e..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
-<html>
-<head>
-   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-   <meta name="GENERATOR" content="Mozilla/4.79 [en] (Windows NT 5.0; U) [Netscape]">
-   <meta name="Author" content="Phil Burk">
-   <meta name="Description" content="PortAudio Docs, a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function.">
-   <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,">
-   <title>PortAudio Docs</title>
-</head>
-<body>
-&nbsp;
-<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" >
-<tr>
-<td>
-<center>
-<h1>
-PortAudio Documentation</h1></center>
-</td>
-</tr>
-</table></center>
-
-<p>Copyright 2000 Phil Burk and Ross Bencina
-<h3>
-<a href="pa_tutorial.html">Tutorial</a></h3>
-
-<dl>
-<dl>Describes how to write audio programs using the PortAudio API.</dl>
-
-<h3>
-<a href="portaudio_h.txt">API Reference</a></h3>
-
-<dl>The Application Programmer Interface is documented in "portaudio.h".</dl>
-
-<h3>
-<a href="releases.html">Release Notes</a></h3>
-
-<dl>What changed since the last release?</dl>
-</dl>
-
-<h3>
-<a href="pa_impl_guide.html">Implementation Guide</a></h3>
-
-<blockquote>Describes how to write an implementation of PortAudio for a
-new computer platform.</blockquote>
-
-<h3>
-<a href="portaudio_icmc2001.pdf">Paper Presented at ICMC2001</a> (PDF)</h3>
-
-<blockquote>Describes the PortAudio API and discusses implementation issues.
-Written July 2001.</blockquote>
-
-<h3>
-<a href="latency.html">Improving Latency</a></h3>
-
-<blockquote>How to tune your computer to achieve the lowest possible audio
-delay.</blockquote>
-
-<h3>
-<a href="proposals.html">Proposed Changes</a></h3>
-
-<blockquote>Describes API changes being considered by the developer community.
-Feedback welcome.</blockquote>
-<a href="http://www.portaudio.com/">Return to PortAudio Home Page</a>
-</body>
-</html>
diff --git a/docs/latency.html b/docs/latency.html
deleted file mode 100644 (file)
index 87f1d12..0000000
+++ /dev/null
@@ -1,192 +0,0 @@
-<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
-<html>
-<head>
-   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-   <meta name="GENERATOR" content="Mozilla/4.79 [en] (Windows NT 5.0; U) [Netscape]">
-   <meta name="Author" content="Phil Burk">
-   <meta name="Description" content="Internal docs. How a stream is started or stopped.">
-   <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,">
-   <title>PortAudio Implementation - Start/Stop</title>
-</head>
-<body>
-&nbsp;
-<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" >
-<tr>
-<td>
-<center>
-<h1>
-<a href="http://www.portaudio.com">PortAudio</a> Latency</h1></center>
-</td>
-</tr>
-</table></center>
-
-<p>This page discusses the issues of audio latency for <a href="http://www.portaudio.com">PortAudio</a>
-. It offers suggestions on how to lower latency to improve the responsiveness
-of applications.
-<blockquote><b><a href="#what">What is Latency?</a></b>
-<br><b><a href="#portaudio">PortAudio and Latency</a></b>
-<br><b><a href="#macintosh">Macintosh</a></b>
-<br><b><a href="#unix">Unix</a></b>
-<br><b><a href="#windows">WIndows</a></b></blockquote>
-By Phil Burk, Copyright 2002 Phil Burk and Ross Bencina
-<h2>
-<a NAME="what"></a>What is Latency?</h2>
-Latency is basically longest time that you have to wait before you obtain
-a desired result. For digital audio output it is the time between making
-a sound in software and finally hearing it.
-<p>Consider the example of pressing a key on the ASCII keyboard to play
-a note. There are several stages in this process which each contribute
-their own latency. First the operating system must respond to the keypress.
-Then the audio signal generated must work its way through the PortAudio
-buffers. Then it must work its way through the audio card hardware. Then
-it must go through the audio amplifier which is very quick and then travel
-through the air. Sound travels at abous one foot per millisecond through
-air so placing speakers across the room can add 5-20 msec of delay.
-<p>The reverse process occurs when recording or responding to audio input.
-If you are processing audio, for example if you implement a software guitar
-fuzz box, then you have both the audio input and audio output latencies
-added together.
-<p>The audio buffers are used to prevent glitches in the audio stream.
-The user software writes audio into the output buffers. That audio is read
-by the low level audio driver or by DMA and sent to the DAC. If the computer
-gets busy doing something like reading the disk or redrawing the screen,
-then it may not have time to fill the audio buffer. The audio hardware
-then runs out of audio data, which causes a glitch. By using a large enough
-buffer we can ensure that there is always enough audio data for the audio
-hardware to play. But if the buffer is too large then the latency is high
-and the system feels sluggish. If you play notes on the keyboard then the
-"instrument" will feel unresponsive. So you want the buffers to be as small
-as possible without glitching.
-<h2>
-<a NAME="portaudio"></a>PortAudio and Latency</h2>
-The only delay that PortAudio can control is the total length of its buffers.
-The Pa_OpenStream() call takes two parameters: numBuffers and framesPerBuffer.
-The latency is also affected by the sample rate which we will call framesPerSecond.
-A frame is a set of samples that occur simultaneously. For a stereo stream,
-a frame is two samples.
-<p>The latency in milliseconds due to this buffering&nbsp; is:
-<blockquote><tt>latency_msec = 1000 * numBuffers * framesPerBuffer / framesPerSecond</tt></blockquote>
-This is not the total latency, as we have seen, but it is the part we can
-control.
-<p>If you call Pa_OpenStream() with numBuffers equal to zero, then PortAudio
-will select a conservative number that will prevent audio glitches. If
-you still get glitches, then you can pass a larger value for numBuffers
-until the glitching stops. if you try to pass a numBuffers value that is
-too small, then PortAudio will use its own idea of the minimum value.
-<p>PortAudio decides on the minimum number of buffers in a conservative
-way based on the frameRate, operating system and other variables. You can
-query the value that PortAudio will use by calling:
-<blockquote><tt>int Pa_GetMinNumBuffers( int framesPerBuffer, double sampleRate
-);</tt></blockquote>
-On some systems you can override the PortAudio minimum if you know your
-system can handle a lower value. You do this by setting an environment
-variable called PA_MIN_LATENCY_MSEC which is read by PortAudio when it
-starts up. This is supported on the PortAudio implementations for Windows
-MME, Windows DirectSound, and Unix OSS.
-<h2>
-<a NAME="macintosh"></a>Macintosh</h2>
-The best thing you can do to improve latency on Mac OS 8 and 9 is to turn
-off Virtual Memory. PortAudio V18 will detect that Virtual Memory is turned
-off and use a very low latency.
-<p>For Mac OS X the latency is very low because Apple Core Audio is so
-well written. You can set the PA_MIN_LATENCY_MSEC variable using:
-<blockquote><tt>setenv PA_MIN_LATENCY_MSEC 4</tt></blockquote>
-
-<h2>
-<a NAME="unix"></a>Unix</h2>
-PortAudio under Unix currently uses a backgroud thread that reads and writes
-to OSS. This gives you decent but not great latency. But if you raise the
-priority of the background thread to a very priority then you can get under
-10 milliseconds latency. In order to raise your priority you must run the
-PortAudio program as root! You must also set PA_MIN_LATENCY_MSEC using
-the appropriate command for your shell.
-<h2>
-<a NAME="windows"></a>Windows</h2>
-Latency under Windows is a complex issue because of all the alternative
-operating system versions and device drivers. I have seen latency range
-from 8 milliseconds to 400 milliseconds. The worst case is when using Windows
-NT. Windows 98 is a little better, and Windows XP can be quite good if
-properly tuned.
-<p>The underlying audio API also makes a lot of difference. If the audio
-device has its own DirectSound driver then DirectSound can often provide
-better latency than WMME. But if a real DirectSound driver is not available
-for your device then it is emulated using WMME and the latency can be very
-high. That's where I saw the 400 millisecond latency. The ASIO implementation
-is generally very good and will give the lowest latency if available.
-<p>You can set the PA_MIN_LATENCY_MSEC variable to 50, for example, by
-entering in MS-DOS:
-<blockquote><tt>set PA_MIN_LATENCY_MSEC=50</tt></blockquote>
-If you enter this in a DOS window then you must run the PortAudio program
-from that same window for the variable to have an effect. You can add that
-line to your C:\AUTOEXEC.BAT file and reboot if you want it to affect any
-PortAudio based program.
-<p>For Windows XP, you can set environment variables as follows:
-<ol>
-<li>
-Select "Control Panel" from the "Start Menu".</li>
-
-<li>
-Launch the "System" Control Panel</li>
-
-<li>
-Click on the "Advanced" tab.</li>
-
-<li>
-Click on the "Environment Variables" button.</li>
-
-<li>
-Click "New" button under&nbsp; User Variables.</li>
-
-<li>
-Enter PA_MIN_LATENCY_MSEC for the name and some optimistic number for the
-value.</li>
-
-<li>
-Click OK, OK, OK.</li>
-</ol>
-
-<h3>
-Improving Latency on Windows</h3>
-There are several steps you can take to improve latency under windows.
-<ol>
-<li>
-Avoid reading or writng to disk when doing audio.</li>
-
-<li>
-Turn off all automated background tasks such as email clients, virus scanners,
-backup programs, FTP servers, web servers, etc. when doing audio.</li>
-
-<li>
-Disconnect from the network to prevent network traffic from interrupting
-your CPU.</li>
-</ol>
-<b>Important: </b>Windows XP users can also tune the OS to favor background
-tasks, such as audio, over foreground tasks, such as word processing. I
-lowered my latency from 40 to 10 milliseconds using this simple technique.
-<ol>
-<li>
-Select "Control Panel" from the "Start Menu".</li>
-
-<li>
-Launch the "System" Control Panel</li>
-
-<li>
-Click on the "Advanced" tab.</li>
-
-<li>
-Click on the "Settings" button in the Performance area.</li>
-
-<li>
-Click on the "Advanced" tab.</li>
-
-<li>
-Select "Background services" in the Processor Scheduling area.</li>
-
-<li>
-Click OK, OK.</li>
-</ol>
-Please let us know if you have others sugestions for lowering latency.
-<br>&nbsp;
-<br>&nbsp;
-</body>
-</html>
diff --git a/docs/pa_impl_guide.html b/docs/pa_impl_guide.html
deleted file mode 100644 (file)
index 50abc30..0000000
+++ /dev/null
@@ -1,197 +0,0 @@
-<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
-<html>
-<head>
-   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-   <meta name="GENERATOR" content="Mozilla/4.79 [en] (Windows NT 5.0; U) [Netscape]">
-   <meta name="Author" content="Phil Burk">
-   <meta name="Description" content="Internal docs. How a stream is started or stopped.">
-   <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,">
-   <title>PortAudio Implementation - Start/Stop</title>
-</head>
-<body>
-&nbsp;
-<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" >
-<tr>
-<td>
-<center>
-<h1>
-<a href="http://www.portaudio.com">PortAudio</a> Implementation Guide</h1></center>
-</td>
-</tr>
-</table></center>
-
-<p>This document describes how to implement the PortAudio API on a new
-computer platform. Implementing PortAudio on a new platform, makes it possible
-to port many existing audio applications to that platform.
-<p>By Phil Burk
-<br>Copyright 2000 Phil Burk and Ross Bencina
-<p>Note that the license says: <b>"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."</b>.
-So when you have finished a new implementation, please send it back to
-us at&nbsp; "<a href="http://www.portaudio.com">http://www.portaudio.com</a>"
-so that we can make it available for other users. Thank you!
-<h2>
-Download the Latest PortAudio Implementation</h2>
-Always start with the latest implementation available at "<a href="http://www.portaudio.com">http://www.portaudio.com</a>".
-Look for the nightly snapshot under the CVS section.
-<h2>
-Select an Existing Implementation as a Basis</h2>
-The fastest way to get started is to take an existing implementation and
-translate it for your new platform. Choose an implementation whose architecture
-is as close as possible to your target.
-<ul>
-<li>
-DirectSound Implementation - pa_win_ds - Uses a timer callback for the
-background "thread". Polls a circular buffer and writes blocks of data
-to keep it full.</li>
-
-<li>
-Windows MME - pa_win_wmme - Spawns an actual Win32 thread. Writes blocks
-of data to the HW device and waits for events that signal buffer completion.</li>
-
-<li>
-Linux OSS - pa_linux - Spawns a real thread that writes to the "/dev/dsp"
-stream using blocking I/O calls.</li>
-</ul>
-When you write a new implementation, you will be using some code that is
-in common with all implementations. This code is in the folder "pa_common".
-It provides various functions such as parameter checking, error code to
-text conversion, sample format conversion, clipping and dithering, etc.
-<p>The code that you write will go into a separate folder called "pa_{os}_{api}".
-For example, code specific to the DirectSound interface for Windows goes
-in "pa_win_ds".
-<h2>
-Read Docs and Code</h2>
-Famialiarize yourself with the system by reading the documentation provided.
-here is a suggested order:
-<ol>
-<li>
-User Programming <a href="pa_tutorial.html">Tutorial</a></li>
-
-<li>
-Header file "pa_common/portaudio.h" which defines API.</li>
-
-<li>
-Header file "pa_common/pa_host.h" for host dependant code. This definces
-the routine you will need to provide.</li>
-
-<li>
-Shared code in "pa_common/pa_lib.c".</li>
-
-<li>
-Docs on Implementation of <a href="pa_impl_startstop.html">Start/Stop</a>
-code.</li>
-</ol>
-
-<h2>
-Implement&nbsp; Output to Default Device</h2>
-Now we are ready to crank some code. For instant gratification, let's try
-to play a sine wave.
-<ol>
-<li>
-Link the test program "pa_tests/patest_sine.c" with the file "pa_lib.c"
-and the implementation specific file you are creating.</li>
-
-<li>
-For now, just stub out the device query code and the audio input code.</li>
-
-<li>
-Modify PaHost_OpenStream() to open your default target device and get everything
-setup.</li>
-
-<li>
-Modify PaHost_StartOutput() to start playing audio.</li>
-
-<li>
-Modify PaHost_StopOutput() to stop audio.</li>
-
-<li>
-Modify PaHost_CloseStream() to clean up. Free all memory that you allocated
-in PaHost_OpenStream().</li>
-
-<li>
-Keep cranking until you can play a sine wave using "patest_sine.c".</li>
-
-<li>
-Once that works, try "patest_pink.c", "patest_clip.c", "patest_sine8.c".</li>
-
-<li>
-To test your Open and Close code, try "patest_many.c".</li>
-
-<li>
-Now test to make sure that the three modes of stopping are properly supported
-by running "patest_stop.c".</li>
-
-<li>
-Test your implementation of time stamping with "patest_sync.c".</li>
-</ol>
-
-<h2>
-Implement Device Queries</h2>
-Now that output is working, lets implement the code for querying what devices
-are available to the user. Run "pa_tests/pa_devs.c". It should print all
-of the devices available and their characteristics.
-<h2>
-Implement Input</h2>
-Implement audio input and test it with:
-<ol>
-<li>
-patest_record.c - record in half duplex, play back as recorded.</li>
-
-<li>
-patest_wire.c - full duplex, copies input to output. Note that some HW
-may not support full duplex.</li>
-
-<li>
-patest_fuzz.c - plug in your guitar and get a feel for why latency is an
-important issue in computer music.</li>
-
-<li>
-paqa_devs.c - try to open every device and use it with every possible format</li>
-</ol>
-
-<h2>
-Debugging Tools</h2>
-You generally cannot use printf() calls to debug real-time processes because
-they disturb the timing. Also calling printf() from your background thread
-or interrupt could crash the machine. So PA includes a tool for capturing
-events and storing the information while it is running. It then prints
-the events when Pa_Terminate() is called.
-<ol>
-<li>
-To enable trace mode, change TRACE_REALTIME_EVENTS in "pa_common/pa_trace.h"
-from a (0) to a (1).</li>
-
-<li>
-Link with "pa_common/pa_trace.c".</li>
-
-<li>
-Add trace messages to your code by calling:</li>
-
-<br><tt>&nbsp;&nbsp; void AddTraceMessage( char *msg, int data );</tt>
-<br><tt>for example</tt>
-<br><tt>&nbsp;&nbsp; AddTraceMessage("Pa_TimeSlice: past_NumCallbacks ",
-past->past_NumCallbacks );</tt>
-<li>
-Run your program. You will get a dump of events at the end.</li>
-
-<li>
-You can leave the trace messages in your code. They will turn to NOOPs
-when you change TRACE_REALTIME_EVENTS back to (0).</li>
-</ol>
-
-<h2>
-Delivery</h2>
-Please send your new code along with notes on the implementation back to
-us at "<a href="http://www.portaudio.com">http://www.portaudio.com</a>".
-We will review the implementation and post it with your name. If you had
-to make any modifications to the code in "pa_common" or "pa_tests" <b>please</b>
-send us those modifications and your notes. We will try to merge your changes
-so that the "pa_common" code works with <b>all</b> implementations.
-<p>If you have suggestions for how to make future implementations easier,
-please let us know.
-<br>THANKS!
-<br>&nbsp;
-</body>
-</html>
diff --git a/docs/pa_impl_startstop.html b/docs/pa_impl_startstop.html
deleted file mode 100644 (file)
index 0f2d0ce..0000000
+++ /dev/null
@@ -1,190 +0,0 @@
-<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
-<html>
-<head>
-   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-   <meta name="GENERATOR" content="Mozilla/4.75 [en]C-gatewaynet  (Win98; U) [Netscape]">
-   <meta name="Author" content="Phil Burk">
-   <meta name="Description" content="Internal docs. How a stream is started or stopped.">
-   <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,">
-   <title>PortAudio Implementation - Start/Stop</title>
-</head>
-<body>
-&nbsp;
-<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" >
-<tr>
-<td>
-<center>
-<h1>
-PortAudio Implementation</h1></center>
-</td>
-</tr>
-</table></center>
-
-<h2>
-Starting and Stopping Streams</h2>
-PortAudio is generally executed in two "threads". The foreground thread
-is the application thread. The background "thread" may be implemented as
-an actual thread, an interrupt handler, or a callback from a timer thread.
-<p>There are three ways that PortAudio can stop a stream. In each case
-we look at the sequence of events and the messages sent between the two
-threads. The following variables are contained in the internalPortAudioStream.
-<blockquote><tt>int&nbsp;&nbsp; past_IsActive;&nbsp;&nbsp;&nbsp;&nbsp;
-/* Background is still playing. */</tt>
-<br><tt>int&nbsp;&nbsp; past_StopSoon;&nbsp;&nbsp;&nbsp;&nbsp; /* Stop
-when last buffer done. */</tt>
-<br><tt>int&nbsp;&nbsp; past_StopNow;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*
-Stop IMMEDIATELY. */</tt></blockquote>
-
-<h3>
-Pa_AbortStream()</h3>
-This function causes the background thread to terminate as soon as possible
-and audio I/O to stop abruptly.
-<br>&nbsp;
-<table BORDER COLS=2 WIDTH="60%" >
-<tr>
-<td><b>Foreground Thread</b></td>
-
-<td><b>Background Thread</b></td>
-</tr>
-
-<tr>
-<td>sets <tt>StopNow</tt></td>
-
-<td></td>
-</tr>
-
-<tr>
-<td></td>
-
-<td>sees <tt>StopNow</tt>,&nbsp;</td>
-</tr>
-
-<tr>
-<td></td>
-
-<td>clears IsActive, stops thread</td>
-</tr>
-
-<tr>
-<td>waits for thread to exit</td>
-
-<td></td>
-</tr>
-
-<tr>
-<td>turns off audio I/O</td>
-
-<td></td>
-</tr>
-</table>
-
-<h3>
-Pa_StopStream()</h3>
-This function stops the user callback function from being called and then
-waits for all audio data written to the output buffer to be played. In
-a system with very low latency, you may not hear any difference between
-<br>&nbsp;
-<table BORDER COLS=2 WIDTH="60%" >
-<tr>
-<td><b>Foreground Thread</b></td>
-
-<td><b>Background Thread</b></td>
-</tr>
-
-<tr>
-<td>sets StopSoon</td>
-
-<td></td>
-</tr>
-
-<tr>
-<td></td>
-
-<td>stops calling user callback</td>
-</tr>
-
-<tr>
-<td></td>
-
-<td>continues until output buffer empty</td>
-</tr>
-
-<tr>
-<td></td>
-
-<td>clears IsActive, stops thread</td>
-</tr>
-
-<tr>
-<td>waits for thread to exit</td>
-
-<td></td>
-</tr>
-
-<tr>
-<td>turns off audio I/O</td>
-
-<td></td>
-</tr>
-</table>
-
-<h3>
-User callback returns one.</h3>
-If the user callback returns one then the user callback function will no
-longer be called. Audio output will continue until all audio data written
-to the output buffer has been played. Then the audio I/O is stopped, the
-background thread terminates, and the stream becomes inactive.
-<br>&nbsp;
-<table BORDER COLS=2 WIDTH="60%" >
-<tr>
-<td><b>Foreground Thread</b></td>
-
-<td><b>Background Thread</b></td>
-</tr>
-
-<tr>
-<td></td>
-
-<td>callback returns 1</td>
-</tr>
-
-<tr>
-<td></td>
-
-<td>sets StopSoon</td>
-</tr>
-
-<tr>
-<td></td>
-
-<td>stops calling user callback</td>
-</tr>
-
-<tr>
-<td></td>
-
-<td>continues until output buffer empty</td>
-</tr>
-
-<tr>
-<td></td>
-
-<td>clears IsActive, stops thread</td>
-</tr>
-
-<tr>
-<td>waits for thread to exit</td>
-
-<td></td>
-</tr>
-
-<tr>
-<td>turns off audio I/O</td>
-
-<td></td>
-</tr>
-</table>
-
-<br>&nbsp;
-</body>
-</html>
diff --git a/docs/pa_tut_asio.html b/docs/pa_tut_asio.html
deleted file mode 100644 (file)
index 1c3e5bf..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
-<html>
-<head>
-   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-   <meta name="GENERATOR" content="Mozilla/4.77 [en]C-gatewaynet  (Win98; U) [Netscape]">
-   <meta name="Author" content="Phil Burk">
-   <meta name="Description" content="Tutorial for PortAudio, a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function.">
-   <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,">
-   <title>PortAudio Tutorial</title>
-</head>
-<body>
-&nbsp;
-<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" >
-<tr>
-<td>
-<center>
-<h1>
-PortAudio Tutorial</h1></center>
-</td>
-</tr>
-</table></center>
-
-<h2>
-Compiling for ASIO (Windows or Macintosh)</h2>
-
-<blockquote>ASIO is a low latency audio API from Steinberg. To compile
-an ASIO application, you must first <a href="http://www.steinberg.net/developers/ASIO2SDKAbout.phtml">download
-the ASIO SDK</a> from Steinberg. You also need to obtain ASIO drivers for
-your audio device.
-<p>Note: I am using '/' as a file separator below. On Macintosh replace
-'/' with ':'. On Windows, replace '/' with '\'.
-<p>&nbsp;To use ASIO with the PortAudio library add the following source
-files to your project:
-<blockquote>
-<pre>pa_asio/pa_asio.cpp</pre>
-</blockquote>
-and also these files from the ASIO SDK:
-<blockquote>
-<pre>common/asio.cpp
-host/asiodrivers.cpp
-host/asiolist.cpp</pre>
-</blockquote>
-and add these directories to the path for include files
-<blockquote>
-<pre>asiosdk2/host/pc&nbsp;&nbsp; (for Windows)
-asiosdk2/common
-asiosdk2/host</pre>
-</blockquote>
-You may try compiling the "pa_tests/patest_saw.c" file first because it
-is the simplest.</blockquote>
-<font size=+2><a href="http://www.portaudio.com/">home</a> |
-<a href="pa_tutorial.html">contents</a>
-| <a href="pa_tut_over.html">previous</a> |&nbsp; <a href="pa_tut_callback.html">next</a></font>
-</body>
-</html>
diff --git a/docs/pa_tut_callback.html b/docs/pa_tut_callback.html
deleted file mode 100644 (file)
index f5ccaf0..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
-<html>
-<head>
-   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-   <meta name="GENERATOR" content="Mozilla/4.77 [en]C-gatewaynet  (Win98; U) [Netscape]">
-   <meta name="Author" content="Phil Burk">
-   <meta name="Description" content="Tutorial for PortAudio, a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function.">
-   <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,">
-   <title>PortAudio Tutorial</title>
-</head>
-<body>
-&nbsp;
-<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" >
-<tr>
-<td>
-<center>
-<h1>
-PortAudio Tutorial</h1></center>
-</td>
-</tr>
-</table></center>
-
-<h2>
-Writing a Callback Function</h2>
-
-<blockquote>To write a program using PortAudio, you must include the "portaudio.h"
-include file. You may wish to read "<a href="portaudio_h.txt">portaudio.h</a>"
-because it contains a complete description of the PortAudio functions and
-constants.
-<blockquote>
-<pre>#include "portaudio.h"</pre>
-</blockquote>
-The next task is to write your custom callback function. It is a function
-that is called by the PortAudio engine whenever it has captured audio data,
-or when it needs more audio data for output.
-<p>Your callback function is often called by an interrupt, or low level
-process so you should not do any complex system activities like allocating
-memory, or reading or writing files, or printf(). Just crunch numbers and
-generate audio signals. What is safe or not safe will vary from platform
-to platform. On the Macintosh, for example, you can only call "interrupt
-safe" routines. Also do not call any PortAudio functions in the callback
-except for Pa_StreamTime() and Pa_GetCPULoad().
-<p>Your callback function must return an int and accept the exact parameters
-specified in this typedef:
-<blockquote>
-<pre>typedef int (PortAudioCallback)(
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void *inputBuffer, void *outputBuffer,
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned long framesPerBuffer,
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PaTimestamp outTime, void *userData );</pre>
-</blockquote>
-Here is an example callback function from the test file "patests/patest_saw.c".
-It calculates a simple left and right sawtooth signal and writes it to
-the output buffer. Notice that in this example, the signals are of <tt>float</tt>
-data type. The signals must be between -1.0 and +1.0. You can also use
-16 bit integers or other formats which are specified during setup. You
-can pass a pointer to your data structure through PortAudio which will
-appear as <tt>userData</tt>.
-<blockquote>
-<pre>int patestCallback(&nbsp; void *inputBuffer, void *outputBuffer,
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned long framesPerBuffer,
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PaTimestamp outTime, void *userData )
-{
-&nbsp;&nbsp;&nbsp; unsigned int i;
-/* Cast data passed through stream to our structure type. */
-&nbsp;&nbsp;&nbsp; paTestData *data = (paTestData*)userData;
-&nbsp;&nbsp;&nbsp; float *out = (float*)outputBuffer;
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-&nbsp;&nbsp;&nbsp; for( i=0; i&lt;framesPerBuffer; i++ )
-&nbsp;&nbsp;&nbsp; {
-&nbsp;&nbsp;&nbsp; /* Stereo channels are interleaved. */
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *out++ = data->left_phase;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* left */
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *out++ = data->right_phase;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* right */
-
-&nbsp;&nbsp;&nbsp; /* Generate simple sawtooth phaser that ranges between -1.0 and 1.0. */
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; data->left_phase += 0.01f;
-&nbsp;&nbsp;&nbsp; /* When signal reaches top, drop back down. */
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( data->left_phase >= 1.0f ) data->left_phase -= 2.0f;
-
-&nbsp;&nbsp;&nbsp; /* higher pitch so we can distinguish left and right. */
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; data->right_phase += 0.03f;&nbsp;
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( data->right_phase >= 1.0f ) data->right_phase -= 2.0f;
-&nbsp;&nbsp;&nbsp; }
-&nbsp;&nbsp;&nbsp; return 0;
-}</pre>
-</blockquote>
-</blockquote>
-<font size=+2><a href="http://www.portaudio.com/">home</a> |
-<a href="pa_tutorial.html">contents</a>
-| <a href="pa_tut_over.html">previous</a> |&nbsp; <a href="pa_tut_init.html">next</a></font>
-</body>
-</html>
diff --git a/docs/pa_tut_devs.html b/docs/pa_tut_devs.html
deleted file mode 100644 (file)
index 1756992..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
-<html>
-<head>
-   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-   <meta name="GENERATOR" content="Mozilla/4.75 [en]C-gatewaynet  (Win98; U) [Netscape]">
-   <meta name="Author" content="Phil Burk">
-   <meta name="Description" content="Tutorial for PortAudio, a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function.">
-   <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,">
-   <title>PortAudio Tutorial</title>
-</head>
-<body>
-&nbsp;
-<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" >
-<tr>
-<td>
-<center>
-<h1>
-PortAudio Tutorial</h1></center>
-</td>
-</tr>
-</table></center>
-
-<h2>
-Querying for Available Devices</h2>
-
-<blockquote>There are often several different audio devices available in
-a computer with different capabilities. They can differ in the sample rates
-supported, bit widths, etc. PortAudio provides a simple way to query for
-the available devices, and then pass the selected device to Pa_OpenStream().
-For an example, see the file "pa_tests/pa_devs.c".
-<p>To determine the number of devices:
-<blockquote>
-<pre>numDevices = Pa_CountDevices();</pre>
-</blockquote>
-You can then query each device in turn by calling Pa_GetDeviceInfo() with
-an index.
-<blockquote>
-<pre>for( i=0; i&lt;numDevices; i++ ) {
-&nbsp;&nbsp;&nbsp;&nbsp; pdi = Pa_GetDeviceInfo( i );</pre>
-</blockquote>
-It will return a pointer to a <tt>PaDeviceInfo</tt> structure which is
-defined as:
-<blockquote>
-<pre>typedef struct{
-&nbsp;&nbsp;&nbsp; int structVersion;&nbsp;
-&nbsp;&nbsp;&nbsp; const char *name;
-&nbsp;&nbsp;&nbsp; int maxInputChannels;
-&nbsp;&nbsp;&nbsp; int maxOutputChannels;
-/* Number of discrete rates, or -1 if range supported. */
-&nbsp;&nbsp;&nbsp; int numSampleRates;
-/* Array of supported sample rates, or {min,max} if range supported. */
-&nbsp;&nbsp;&nbsp; const double *sampleRates;
-&nbsp;&nbsp;&nbsp; PaSampleFormat nativeSampleFormat;
-}PaDeviceInfo;</pre>
-</blockquote>
-If the device supports a continuous range of sample rates, then numSampleRates
-will equal -1, and the sampleRates array will have two values, the minimum&nbsp;
-and maximum rate.
-<p>The device information is allocated by Pa_Initialize() and freed by
-Pa_Terminate() so you do not have to free() the structure returned by Pa_GetDeviceInfo().</blockquote>
-<font size=+2><a href="http://www.portaudio.com/">home</a> |
-<a href="pa_tutorial.html">contents</a>
-| <a href="pa_tut_util.html">previous</a> |&nbsp; <a href="pa_tut_rw.html">next</a></font>
-</body>
-</html>
diff --git a/docs/pa_tut_explore.html b/docs/pa_tut_explore.html
deleted file mode 100644 (file)
index 91c08a5..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
-<html>
-<head>
-   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-   <meta name="GENERATOR" content="Mozilla/4.73 [en]C-gatewaynet  (Win98; U) [Netscape]">
-   <meta name="Author" content="Phil Burk">
-   <meta name="Description" content="Tutorial for PortAudio, a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function.">
-   <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,">
-   <title>PortAudio Tutorial</title>
-</head>
-<body>
-&nbsp;
-<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" >
-<tr>
-<td>
-<center>
-<h1>
-PortAudio Tutorial</h1></center>
-</td>
-</tr>
-</table></center>
-
-<h2>
-Exploring PortAudio</h2>
-
-<blockquote>Now that you have a good idea of how PortAudio works, you can
-try out the test programs.
-<ul>
-<li>
-For an example of playing a sine wave, see "pa_tests/patest_sine.c".</li>
-
-<li>
-For an example of recording and playing back a sound, see&nbsp; "pa_tests/patest_record.c".</li>
-</ul>
-I also encourage you to examine the source for the PortAudio libraries.
-If you have suggestions on ways to improve them, please let us know. if
-you want to implement PortAudio on a new platform, please let us know as
-well so we can coordinate people's efforts.</blockquote>
-<font size=+2><a href="http://www.portaudio.com/">home</a> | <a href="pa_tutorial.html">contents</a>
-| <a href="pa_tut_rw.html">previous</a> |&nbsp; next</font>
-</body>
-</html>
diff --git a/docs/pa_tut_init.html b/docs/pa_tut_init.html
deleted file mode 100644 (file)
index 91bfa8d..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
-<html>
-<head>
-   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-   <meta name="GENERATOR" content="Mozilla/4.73 [en]C-gatewaynet  (Win98; U) [Netscape]">
-   <meta name="Author" content="Phil Burk">
-   <meta name="Description" content="Tutorial for PortAudio, a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function.">
-   <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,">
-   <title>PortAudio Tutorial</title>
-</head>
-<body>
-&nbsp;
-<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" >
-<tr>
-<td>
-<center>
-<h1>
-PortAudio Tutorial</h1></center>
-</td>
-</tr>
-</table></center>
-
-<h2>
-Initializing PortAudio</h2>
-
-<blockquote>Before making any other calls to PortAudio, you must call <tt>Pa_Initialize</tt>().
-This will trigger a scan of available devices which can be queried later.
-Like most PA functions, it will return a result of type <tt>paError</tt>.
-If the result is not <tt>paNoError</tt>, then an error has occurred.
-<blockquote>
-<pre>err = Pa_Initialize();
-if( err != paNoError ) goto error;</pre>
-</blockquote>
-You can get a text message that explains the error message by passing it
-to
-<blockquote>
-<pre>printf(&nbsp; "PortAudio error: %s\n", Pa_GetErrorText( err ) );</pre>
-</blockquote>
-</blockquote>
-<font size=+2><a href="http://www.portaudio.com/">home</a> | <a href="pa_tutorial.html">contents</a>
-| <a href="pa_tut_callback.html">previous</a> |&nbsp; <a href="pa_tut_open.html">next</a></font>
-</body>
-</html>
diff --git a/docs/pa_tut_mac.html b/docs/pa_tut_mac.html
deleted file mode 100644 (file)
index bf3dafd..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
-<html>
-<head>
-   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-   <meta name="GENERATOR" content="Mozilla/4.77 [en]C-gatewaynet  (Win98; U) [Netscape]">
-   <meta name="Author" content="Phil Burk">
-   <meta name="Description" content="Tutorial for PortAudio, a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function.">
-   <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,">
-   <title>PortAudio Tutorial</title>
-</head>
-<body>
-&nbsp;
-<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" >
-<tr>
-<td>
-<center>
-<h1>
-PortAudio Tutorial</h1></center>
-</td>
-</tr>
-</table></center>
-
-<h2>
-Compiling for Macintosh</h2>
-
-<blockquote>To compile a Macintosh application with the PortAudio library,
-add the following source files to your project:
-<blockquote>
-<pre>pa_mac:pa_mac.c
-pa_common:pa_lib.c
-pa_common:portaudio.h
-pa_common:pa_host.h</pre>
-</blockquote>
-Also add the Apple <b>SoundLib</b> to your project.
-<p>You may try compiling the "pa_tests:patest_saw.c" file first because
-it is the simplest.</blockquote>
-<font size=+2><a href="http://www.portaudio.com/">home</a> |
-<a href="pa_tutorial.html">contents</a>
-| <a href="pa_tut_over.html">previous</a> |&nbsp; <a href="pa_tut_callback.html">next</a></font>
-</body>
-</html>
diff --git a/docs/pa_tut_mac_osx.html b/docs/pa_tut_mac_osx.html
deleted file mode 100644 (file)
index 3af8c14..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
-<html>
-<head>
-   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-   <meta name="GENERATOR" content="Mozilla/4.79 [en] (Windows NT 5.0; U) [Netscape]">
-   <meta name="Author" content="Phil Burk">
-   <meta name="Description" content="Tutorial for PortAudio, a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function.">
-   <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,">
-   <title>PortAudio Tutorial</title>
-</head>
-<body>
-&nbsp;
-<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" >
-<tr>
-<td>
-<center>
-<h1>
-PortAudio Tutorial</h1></center>
-</td>
-</tr>
-</table></center>
-
-<h2>
-Compiling for Macintosh OS X</h2>
-
-<blockquote>To compile a Macintosh OS X CoreAudio application with the
-PortAudio library:
-<p>Create a new ProjectBuilder project. You can use a "Tool" project to
-run the PortAudio examples.
-<p>Add the following source files to your Project:
-<blockquote>
-<pre>pa_mac_core/pa_mac_core.c
-pa_common/pa_lib.c
-pa_common/portaudio.h
-pa_common/pa_host.h
-pa_common/pa_convert.c</pre>
-</blockquote>
-Add the Apple CoreAudio.framework to your project by selecting "Add FrameWorks..."
-from the Project menu.
-<p>Compile and run the "pa_tests:patest_saw.c" file first because it is
-the simplest.</blockquote>
-<font size=+2><a href="http://www.portaudio.com/">home</a> |
-<a href="pa_tutorial.html">contents</a>
-| <a href="pa_tut_over.html">previous</a> |&nbsp; <a href="pa_tut_callback.html">next</a></font>
-</body>
-</html>
diff --git a/docs/pa_tut_open.html b/docs/pa_tut_open.html
deleted file mode 100644 (file)
index 1621ef3..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
-<html>
-<head>
-   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-   <meta name="GENERATOR" content="Mozilla/4.73 [en]C-gatewaynet  (Win98; U) [Netscape]">
-   <meta name="Author" content="Phil Burk">
-   <meta name="Description" content="Tutorial for PortAudio, a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function.">
-   <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,">
-   <title>PortAudio Tutorial</title>
-</head>
-<body>
-&nbsp;
-<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" >
-<tr>
-<td>
-<center>
-<h1>
-PortAudio Tutorial</h1></center>
-</td>
-</tr>
-</table></center>
-
-<h2>
-Opening a Stream using Defaults</h2>
-
-<blockquote>The next step is to open a stream which is similar to opening
-a file. You can specify whether you want audio input and/or output, how
-many channels, the data format, sample rate, etc. There are two calls for
-opening streams, <tt>Pa_OpenStream</tt>() and <tt>Pa_OpenDefaultStream</tt>().
-<p><tt>Pa_OpenStream()</tt> takes extra&nbsp; parameters which give you
-more control. You can normally just use <tt>Pa_OpenDefaultStream</tt>()
-which just calls <tt>Pa_OpenStream()</tt> <tt>with</tt> some reasonable
-default values.&nbsp; Let's open a stream for stereo output, using floating
-point data, at 44100 Hz.
-<blockquote>
-<pre>err = Pa_OpenDefaultStream(
-&nbsp;&nbsp;&nbsp; &amp;stream,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* passes back stream pointer */
-&nbsp;&nbsp;&nbsp; 0,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* no input channels */
-&nbsp;&nbsp;&nbsp; 2,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* stereo output */
-&nbsp;&nbsp;&nbsp; paFloat32,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* 32 bit floating point output */
-&nbsp;&nbsp;&nbsp; 44100,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* sample rate */
-&nbsp;&nbsp;&nbsp; 256,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* frames per buffer */
-&nbsp;&nbsp;&nbsp; 0,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* number of buffers, if zero then use default minimum */
-&nbsp;&nbsp;&nbsp; patestCallback, /* specify our custom callback */
-&nbsp;&nbsp;&nbsp; &amp;data );&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* pass our data through to callback */</pre>
-</blockquote>
-If you want to use 16 bit integer data, pass <tt>paInt16</tt> instead of
-<tt>paFloat32</tt>.</blockquote>
-<font size=+2><a href="http://www.portaudio.com/">home</a> | <a href="pa_tutorial.html">contents</a>
-| <a href="pa_tut_init.html">previous</a> |&nbsp; <a href="pa_tut_run.html">next</a></font>
-</body>
-</html>
diff --git a/docs/pa_tut_oss.html b/docs/pa_tut_oss.html
deleted file mode 100644 (file)
index 1bb76f2..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
-<html>
-<head>
-   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-   <meta name="GENERATOR" content="Mozilla/4.77 [en]C-gatewaynet  (Win98; U) [Netscape]">
-   <meta name="Author" content="Phil Burk">
-   <meta name="Description" content="Tutorial for PortAudio, a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function.">
-   <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,">
-   <title>PortAudio Tutorial</title>
-</head>
-<body>
-&nbsp;
-<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" >
-<tr>
-<td>
-<center>
-<h1>
-PortAudio Tutorial</h1></center>
-</td>
-</tr>
-</table></center>
-
-<h2>
-Compiling for Unix OSS</h2>
-
-<blockquote>[Skip this page if you are not using Unix and OSS]
-<p>We currently support the <a href="http://www.opensound.com/">OSS</a>
-audio drivers for Linux, Solaris, and FreeBSD. We hope to someday support
-the newer ALSA drivers.
-<ol>
-<li>
-cd to pa_unix_oss directory</li>
-
-<li>
-Edit the Makefile and uncomment one of the tests. You may try compiling
-the "patest_sine.c" file first because it is very simple.</li>
-
-<li>
-gmake run</li>
-</ol>
-</blockquote>
-<font size=+2><a href="http://www.portaudio.com/">home</a> |
-<a href="pa_tutorial.html">contents</a>
-| <a href="pa_tut_pc.html">previous</a> |&nbsp; <a href="pa_tut_callback.html">next</a></font>
-</body>
-</html>
diff --git a/docs/pa_tut_over.html b/docs/pa_tut_over.html
deleted file mode 100644 (file)
index baa9920..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
-<html>
-<head>
-   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-   <meta name="GENERATOR" content="Mozilla/4.79 [en] (Windows NT 5.0; U) [Netscape]">
-   <meta name="Author" content="Phil Burk">
-   <meta name="Description" content="Tutorial for PortAudio, a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function.">
-   <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,">
-   <title>PortAudio Tutorial</title>
-</head>
-<body>
-&nbsp;
-<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" >
-<tr>
-<td>
-<center>
-<h1>
-PortAudio Tutorial</h1></center>
-</td>
-</tr>
-</table></center>
-
-<h2>
-Overview of PortAudio</h2>
-
-<blockquote>PortAudio is a library that provides streaming audio input
-and output. It is a cross-platform API (Application Programming Interface)
-that works on Windows, Macintosh, Unix running OSS, SGI, BeOS, and perhaps
-other platforms by the time you read this. This means that you can write
-a simple 'C' program to process or generate an audio signal, and that program
-can run on several different types of computer just by recompiling the
-source code.
-<p>Here are the steps to writing a PortAudio application:
-<ol>
-<li>
-Write a callback function that will be called by PortAudio when audio processing
-is needed.</li>
-
-<li>
-Initialize the PA library and open a stream for audio I/O.</li>
-
-<li>
-Start the stream. Your callback function will be now be called repeatedly
-by PA in the background.</li>
-
-<li>
-In your callback you can read audio data from the inputBuffer and/or write
-data to the outputBuffer.</li>
-
-<li>
-Stop the stream by returning 1 from your callback, or by calling a stop
-function.</li>
-
-<li>
-Close the stream and terminate the library.</li>
-</ol>
-</blockquote>
-
-<blockquote>There is also <a href="pa_tut_rw.html">another interface</a>
-provided that allows you to generate audio in the foreground. You then
-simply write data to the stream and the tool will not return until it is
-ready to accept more data. This interface is simpler to use but is usually
-not preferred for large applications because it requires that you launch
-a thread to perform the synthesis. Launching a thread may be difficult
-on non-multi-tasking systems such as the Macintosh prior to MacOS X.
-<p>Let's continue by building a simple application that will play a sawtooth
-wave.
-<p>Please select the page for the specific implementation you would like
-to use:
-<ul>
-<li>
-<a href="pa_tut_pc.html">Windows (WMME or DirectSound)</a></li>
-
-<li>
-<a href="pa_tut_mac.html">Macintosh SoundManager for OS 7,8,9</a></li>
-
-<li>
-<a href="pa_tut_mac_osx.html">Macintosh CoreAudio for OS X</a></li>
-
-<li>
-<a href="pa_tut_asio.html">ASIO on Windows or Macintosh</a></li>
-
-<li>
-<a href="pa_tut_oss.html">Unix OSS</a></li>
-</ul>
-or continue with the <a href="pa_tut_callback.html">next page of the programming
-tutorial</a>.</blockquote>
-<font size=+2><a href="http://www.portaudio.com/">home</a> |
-<a href="pa_tutorial.html">contents</a>
-| <a href="pa_tutorial.html">previous</a></font>
-</body>
-</html>
diff --git a/docs/pa_tut_pc.html b/docs/pa_tut_pc.html
deleted file mode 100644 (file)
index 87e5f9a..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
-<html>
-<head>
-   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-   <meta name="GENERATOR" content="Mozilla/4.77 [en]C-gatewaynet  (Win98; U) [Netscape]">
-   <meta name="Author" content="Phil Burk">
-   <meta name="Description" content="Tutorial for PortAudio, a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function.">
-   <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,">
-   <title>PortAudio Tutorial</title>
-</head>
-<body>
-&nbsp;
-<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" >
-<tr>
-<td>
-<center>
-<h1>
-PortAudio Tutorial</h1></center>
-</td>
-</tr>
-</table></center>
-
-<h2>
-Compiling for Windows (WMME or DirectSound)</h2>
-
-<blockquote>To compile PortAudio for Windows, you can choose between two
-options. One implementation uses the DirectSound API. The other uses the
-Windows MultiMedia Extensions API (aka WMME or WAVE).
-<p>Some advantages of using DirectSound are that DirectSound may have lower
-latency than WMME, and supports effects processing plugins. But one disadvantage
-is that DirectSound is not installed on all PCs, and is not well supported
-under Windows NT. So WMME is the best choice for most projects.
-<p>For either implementation add the following source files to your project:
-<blockquote>
-<pre><b>pa_common\pa_lib.c
-pa_common\portaudio.h
-pa_common\pa_host.h</b></pre>
-</blockquote>
-Link with the system library "<b>winmm.lib</b>". For Visual C++:
-<ol>
-<li>
-select "Settings..." from the "Project" menu,</li>
-
-<li>
-select the project name in the tree on the left,</li>
-
-<li>
-choose "All Configurations" in the popup menu above the tree,</li>
-
-<li>
-select the "Link" tab,</li>
-
-<li>
-enter "winmm.lib", without quotes, as the first item in the "Object/library
-modules:" field.</li>
-</ol>
-<b>WMME</b> - To use the WMME implementation, add the following source
-files to your project:
-<blockquote><b><tt>pa_win_wmme/pa_win_wmme.c</tt></b></blockquote>
-<b>DirectSound</b> - If you want to use the DirectSound implementation
-of PortAudio then you must have a recent copy of the free
-<a href="http://www.microsoft.com/directx/download.asp">DirectX</a>
-SDK for Developers from Microsoft installed on your computer. To compile
-an application add the following source files to your project:
-<blockquote>
-<pre><b>pa_win_ds\dsound_wrapper.c
-pa_win_ds\pa_dsound.c</b></pre>
-</blockquote>
-Link with the system library "<b>dsound.lib</b>" using the procedure described
-above for "winmm.lib".</blockquote>
-
-<blockquote>You might try compiling the "pa_tests\patest_saw.c" file first
-because it is the simplest.</blockquote>
-<font size=+2><a href="http://www.portaudio.com/">home</a> |
-<a href="pa_tutorial.html">contents</a>
-| <a href="pa_tut_over.html">previous</a> |&nbsp; <a href="pa_tut_callback.html">next</a></font>
-</body>
-</html>
diff --git a/docs/pa_tut_run.html b/docs/pa_tut_run.html
deleted file mode 100644 (file)
index 5c70d08..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
-<html>
-<head>
-   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-   <meta name="GENERATOR" content="Mozilla/4.73 [en]C-gatewaynet  (Win98; U) [Netscape]">
-   <meta name="Author" content="Phil Burk">
-   <meta name="Description" content="Tutorial for PortAudio, a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function.">
-   <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,">
-   <title>PortAudio Tutorial</title>
-</head>
-<body>
-&nbsp;
-<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" >
-<tr>
-<td>
-<center>
-<h1>
-PortAudio Tutorial</h1></center>
-</td>
-</tr>
-</table></center>
-
-<h2>
-Starting and Stopping a Stream</h2>
-
-<blockquote>The stream will not start running until you call Pa_StartStream().
-Then it will start calling your callback function to perform the audio
-processing.
-<blockquote>
-<pre>err = Pa_StartStream( stream );
-if( err != paNoError ) goto error;</pre>
-</blockquote>
-At this point, audio is being generated. You can communicate to your callback
-routine through the data structure you passed in on the open call, or through
-global variables, or using other interprocess communication techniques.
-Please be aware that your callback function may be called at interrupt
-time when your foreground process is least expecting it. So avoid sharing
-complex data structures that are easily corrupted like double linked lists.
-<p>In many of the tests we simply sleep for a few seconds so we can hear
-the sound. This is easy to do with Pa_Sleep() which will sleep for some
-number of milliseconds. Do not rely on this function for accurate scheduling.
-it is mostly for writing examples.
-<blockquote>
-<pre>/* Sleep for several seconds. */
-Pa_Sleep(NUM_SECONDS*1000);</pre>
-</blockquote>
-When you are through, you can stop the stream from the foreground.
-<blockquote>
-<pre>err = Pa_StopStream( stream );
-if( err != paNoError ) goto error;</pre>
-</blockquote>
-You can also stop the stream by returning 1 from your custom callback function.</blockquote>
-<font size=+2><a href="http://www.portaudio.com/">home</a> | <a href="pa_tutorial.html">contents</a>
-| <a href="pa_tut_open.html">previous</a> |&nbsp; <a href="pa_tut_term.html">next</a></font>
-</body>
-</html>
diff --git a/docs/pa_tut_rw.html b/docs/pa_tut_rw.html
deleted file mode 100644 (file)
index 93c7b8b..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
-<html>
-<head>
-   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-   <meta name="GENERATOR" content="Mozilla/4.77 [en]C-gatewaynet  (Win98; U) [Netscape]">
-   <meta name="Author" content="Phil Burk">
-   <meta name="Description" content="Tutorial for PortAudio, a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function.">
-   <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,">
-   <title>PortAudio Tutorial</title>
-</head>
-<body>
-&nbsp;
-<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" >
-<tr>
-<td>
-<center>
-<h1>
-PortAudio Tutorial</h1></center>
-</td>
-</tr>
-</table></center>
-
-<h2>
-Blocking Read/Write Functions</h2>
-
-<blockquote>[Note: These functions are not part of the official PortAudio
-API. They are simply built on top of PortAudio as an extra utility. Also
-note that they are under evaluation and their definition may change.]
-<p>There are two fundamentally different ways to design an audio API. One
-is to use callback functions the way we have already shown. The callback
-function operates under an interrupt or background thread This leaves the
-foreground application free to do other things while the audio just runs
-in the background. But this can sometimes be awkward.
-<p>So we have provided an alternative technique that lets a program generate
-audio in the foreground and then just write it to the audio stream as if
-it was a file. If there is not enough room in the audio buffer for more
-data, then the write function will just block until more room is available.
-This can make it very easy to write an audio example. To use this tool,
-you must add the files "pablio/pablio.c" and "pablio/ringbuffer.c" to your
-project. You must also:
-<blockquote>
-<pre>#include "pablio.h"</pre>
-</blockquote>
-Here is a short excerpt of a program that opens a stream for input and
-output. It then reads a block of samples from input, and writes them to
-output, in a loop.&nbsp; The complete example can be found in "pablio/test_rw.c".
-<blockquote>
-<pre>&nbsp;&nbsp;&nbsp; #define SAMPLES_PER_FRAME&nbsp;&nbsp;&nbsp;&nbsp; (2)
-&nbsp;&nbsp;&nbsp; #define FRAMES_PER_BLOCK&nbsp;&nbsp;&nbsp; (1024)
-&nbsp;&nbsp;&nbsp; SAMPLE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; samples[SAMPLES_PER_FRAME * FRAMES_PER_BLOCK];
-&nbsp;&nbsp;&nbsp; PaError&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; err;
-&nbsp;&nbsp;&nbsp; PABLIO_Stream&nbsp; *aStream;
-
-/* Open simplified blocking I/O layer on top of PortAudio. */
-&nbsp;&nbsp;&nbsp; err = OpenAudioStream( &amp;rwbl, SAMPLE_RATE, paFloat32,
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (PABLIO_READ_WRITE | PABLIO_STEREO) );
-&nbsp;&nbsp;&nbsp; if( err != paNoError ) goto error;
-
-/* Process samples in the foreground. */
-&nbsp;&nbsp;&nbsp; for( i=0; i&lt;(NUM_SECONDS * SAMPLE_RATE); i++ )
-&nbsp;&nbsp;&nbsp; {
-&nbsp;&nbsp;&nbsp; /* Read one block of data into sample array from audio input. */
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ReadAudioStream( aStream, samples, FRAMES_PER_BLOCK );
-&nbsp;&nbsp;&nbsp; /*
-&nbsp;&nbsp;&nbsp; ** At this point you could process the data in samples array,
-&nbsp;&nbsp;&nbsp; ** and write the result back to the same samples array.
-&nbsp;&nbsp;&nbsp; */
-&nbsp;&nbsp;&nbsp; /* Write that same frame of data to output. */
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WriteAudioStream( aStream, samples, FRAMES_PER_BLOCK );
-&nbsp;&nbsp;&nbsp; }
-
-&nbsp;&nbsp;&nbsp; CloseAudioStream( aStream );</pre>
-</blockquote>
-</blockquote>
-<font size=+2><a href="http://www.portaudio.com/">home</a> |
-<a href="pa_tutorial.html">contents</a>
-| <a href="pa_tut_devs.html">previous</a> |&nbsp; <a href="pa_tut_explore.html">next</a></font>
-</body>
-</html>
diff --git a/docs/pa_tut_term.html b/docs/pa_tut_term.html
deleted file mode 100644 (file)
index 1c72209..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
-<html>
-<head>
-   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-   <meta name="GENERATOR" content="Mozilla/4.73 [en]C-gatewaynet  (Win98; U) [Netscape]">
-   <meta name="Author" content="Phil Burk">
-   <meta name="Description" content="Tutorial for PortAudio, a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function.">
-   <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,">
-   <title>PortAudio Tutorial</title>
-</head>
-<body>
-&nbsp;
-<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" >
-<tr>
-<td>
-<center>
-<h1>
-PortAudio Tutorial</h1></center>
-</td>
-</tr>
-</table></center>
-
-<h2>
-Terminating PortAudio</h2>
-
-<blockquote>You can start and stop a stream as many times as you like.
-But when you are done using it, you should close it by calling:</blockquote>
-
-<blockquote>
-<blockquote>
-<pre>err = Pa_CloseStream( stream );
-if( err != paNoError ) goto error;</pre>
-</blockquote>
-Then when you are done using PortAudio, you should terminate the whole
-system by calling:
-<blockquote>
-<pre>Pa_Terminate();</pre>
-</blockquote>
-That's basically it. You can now write an audio program in 'C' that will
-run on multiple platforms, for example PCs and Macintosh.
-<p>In the rest of the tutorial we will look at some additional utility
-functions, and a different way of using PortAudio that does not require
-the use of a callback function.</blockquote>
-<font size=+2><a href="http://www.portaudio.com/">home</a> | <a href="pa_tutorial.html">contents</a>
-| <a href="pa_tut_run.html">previous</a> |&nbsp; <a href="pa_tut_util.html">next</a></font>
-</body>
-</html>
diff --git a/docs/pa_tut_util.html b/docs/pa_tut_util.html
deleted file mode 100644 (file)
index f4b5475..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
-<html>
-<head>
-   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-   <meta name="GENERATOR" content="Mozilla/4.75 [en]C-gatewaynet  (Win98; U) [Netscape]">
-   <meta name="Author" content="Phil Burk">
-   <meta name="Description" content="Tutorial for PortAudio, a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function.">
-   <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,">
-   <title>PortAudio Tutorial</title>
-</head>
-<body>
-&nbsp;
-<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" >
-<tr>
-<td>
-<center>
-<h1>
-PortAudio Tutorial</h1></center>
-</td>
-</tr>
-</table></center>
-
-<h2>
-Utility Functions</h2>
-
-<blockquote>Here are several more functions that are not critical, but
-may be handy when using PortAudio.
-<p>Pa_StreamActive() returns one when the stream in playing audio, zero
-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.
-<blockquote>
-<pre>PaError Pa_StreamActive( PortAudioStream *stream );</pre>
-</blockquote>
-Pa_StreamTime() returns the number of samples that have been generated.
-PaTimeStamp is a double precision number which is a convenient way to pass
-big numbers around even though we only need integers.
-<blockquote>
-<pre>PaTimestamp Pa_StreamTime( PortAudioStream *stream );</pre>
-</blockquote>
-The "CPU Load" is a fraction of total CPU time consumed by the stream's
-audio processing. 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.
-<blockquote>
-<pre>double Pa_GetCPULoad( PortAudioStream* stream );</pre>
-</blockquote>
-</blockquote>
-<font size=+2><a href="http://www.portaudio.com/">home</a> |
-<a href="pa_tutorial.html">contents</a> | <a href="pa_tut_term.html">previous</a>
-|&nbsp; <a href="pa_tut_devs.html">next</a></font>
-</body>
-</html>
diff --git a/docs/pa_tutorial.html b/docs/pa_tutorial.html
deleted file mode 100644 (file)
index 1371c44..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
-<html>
-<head>
-   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-   <meta name="GENERATOR" content="Mozilla/4.79 [en] (Windows NT 5.0; U) [Netscape]">
-   <meta name="Author" content="Phil Burk">
-   <meta name="Description" content="Tutorial for PortAudio, a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function.">
-   <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,">
-   <title>PortAudio Tutorial</title>
-</head>
-<body>
-&nbsp;
-<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" >
-<tr>
-<td>
-<center>
-<h1>
-PortAudio Tutorial</h1></center>
-</td>
-</tr>
-</table></center>
-
-<p>Copyright 2000 Phil Burk and Ross Bencina
-<h2>
-Table of Contents</h2>
-
-<blockquote><a href="pa_tut_over.html">Overview of PortAudio</a>
-<br><a href="pa_tut_mac.html">Compiling for Macintosh OS 7,8,9</a>
-<br><a href="pa_tut_mac_osx.html">Compiling for Macintosh OS X</a>
-<br><a href="pa_tut_pc.html">Compiling for Windows (DirectSound and WMME)</a>
-<br><a href="pa_tut_asio.html">Compiling for ASIO on Windows or Mac OS
-8,9</a>
-<br><a href="pa_tut_oss.html">Compiling for Unix OSS</a>
-<br><a href="pa_tut_callback.html">Writing a Callback Function</a>
-<br><a href="pa_tut_init.html">Initializing PortAudio</a>
-<br><a href="pa_tut_open.html">Opening a Stream using Defaults</a>
-<br><a href="pa_tut_run.html">Starting and Stopping a Stream</a>
-<br><a href="pa_tut_term.html">Cleaning Up</a>
-<br><a href="pa_tut_util.html">Utilities</a>
-<br><a href="pa_tut_devs.html">Querying for Devices</a>
-<br><a href="pa_tut_rw.html">Blocking Read/Write Functions</a>
-<br><a href="pa_tut_explore.html">Exploring the PortAudio Package</a></blockquote>
-<font size=+2><a href="http://www.portaudio.com/">home</a> | contents |
-previous |&nbsp; <a href="pa_tut_over.html">next</a></font>
-</body>
-</html>
diff --git a/docs/portaudio_h.txt b/docs/portaudio_h.txt
deleted file mode 100644 (file)
index 6d60086..0000000
+++ /dev/null
@@ -1,425 +0,0 @@
-#ifndef PORT_AUDIO_H
-#define PORT_AUDIO_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-/*
- * 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
-} 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 );
-
-/*
-       Return host specific error.
-       This can be called after receiving a paHostError.
-*/
-long Pa_GetHostError( void );
-
-/*
-       Translate the 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 devices.
-
-       The floating point representation uses +1.0 and -1.0 as the respective
-       maximum and minimum.
-       
-*/
-
-typedef unsigned long 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))    /* unsigned 8 bit, 128 is "ground" */
-#define paCustomFormat ((PaSampleFormat) (1<<16))
-
-/*
-       Device enumeration mechanism.
-
-       Device ids range from 0 to Pa_CountDevices()-1.
-
-       Devices may support input, output or both. Device 0 is always the "default"
-       device and should support at least stereo in and out if that is available
-       on the taget platform _even_ if this involves kludging an input/output
-       device on platforms that usually separate input from output. Other platform
-       specific devices are specified by positive device ids.
-*/
-
-typedef int PaDeviceID;
-#define paNoDevice -1
-
-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;
-
-
-int Pa_CountDevices();
-/*
-       Pa_GetDefaultInputDeviceID(), Pa_GetDefaultOutputDeviceID()
-
-       Return the default device ID or paNoDevice if there is no devices.
-       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 ID by using
-       the supplied application "pa_devs".
-*/
-PaDeviceID Pa_GetDefaultInputDeviceID( void );
-PaDeviceID Pa_GetDefaultOutputDeviceID( void );
-
-/*
-       PaTimestamp is used to represent a continuous sample clock with arbitrary
-       start time useful for syncronisation. The type is used in the outTime
-       argument to the callback function and the result of Pa_StreamTime()
-*/
-
-typedef double PaTimestamp;
-
-/*
-       Pa_GetDeviceInfo() returns a pointer to an immutable PaDeviceInfo structure
-       referring to the device specified by id.
-       If id is out of range the function returns NULL.
-
-       The returned structure is owned by the PortAudio implementation and must
-       not be manipulated or freed. The pointer is guaranteed to be valid until
-       between calls to Pa_Initialize() and Pa_Terminate().
-*/
-
-const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceID devID );
-
-/*
-       PortAudioCallback is implemented by clients of the portable audio api.
-
-       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 nonzero 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
-       nonzero 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,
-               unsigned long framesPerBuffer,
-               PaTimestamp outTime, void *userData );
-
-
-/*
-       Stream flags
-
-       These flags may be supplied (ored together) in the streamFlags argument to
-       the Pa_OpenStream() function.
-
-       [ suggestions? ]
-*/
-
-#define   paNoFlag      (0)
-#define   paClipOff     (1<<0)   /* disable defult clipping of out of range samples */
-#define   paDitherOff   (1<<1)   /* disable default dithering */
-#define   paPlatformSpecificFlags (0x00010000)
-typedef   unsigned long 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
-       device input record for the device specified in the inputDevice parameter.
-       If inputDevice is paNoDevice numInputChannels is ignored.
-
-       inputSampleFormat is the 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 sound devices 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 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. 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 behavior 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:
-       Apon 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 nonzero 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,
-                               unsigned long framesPerBuffer,
-                               unsigned long numberOfBuffers,
-                               PaStreamFlags streamFlags,
-                               PortAudioCallback *callback,
-                               void *userData );
-
-
-/*
-       Pa_OpenDefaultStream() is a simplified version of Pa_OpenStream() that
-       opens the default input and/or ouput 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 (same 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,
-                               unsigned long framesPerBuffer,
-                               unsigned long 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 when the stream is playing audio,
-       zero 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 for the stream in samples.
-       This time may be used as a time reference (for example syncronising audio to
-       MIDI).
-*/
-
-PaTimestamp Pa_StreamTime( PortAudioStream *stream );
-
-/*
-       The "CPU Load" is a fraction of total CPU time consumed by the
-       stream's audio processing.
-       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 );
-
-/*
-       Use Pa_GetMinNumBuffers() to determine minimum number of buffers required for
-       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 );
-
-/*
-       Sleep for at least 'msec' milliseconds.
-       You may sleep longer than the requested time so don't rely
-       on this for accurate musical timing.
-*/
-void Pa_Sleep( long msec );
-
-/*
-       Return size in bytes of a single sample in a given PaSampleFormat
-       or paSampleFormatNotSupported. 
-*/
-PaError Pa_GetSampleSize( PaSampleFormat format );
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-#endif /* PORT_AUDIO_H */
diff --git a/docs/portaudio_icmc2001.pdf b/docs/portaudio_icmc2001.pdf
deleted file mode 100644 (file)
index dd074b7..0000000
Binary files a/docs/portaudio_icmc2001.pdf and /dev/null differ
diff --git a/docs/proposals.html b/docs/proposals.html
deleted file mode 100644 (file)
index 88dd2d0..0000000
Binary files a/docs/proposals.html and /dev/null differ
diff --git a/docs/releases.html b/docs/releases.html
deleted file mode 100644 (file)
index aec80a1..0000000
+++ /dev/null
@@ -1,339 +0,0 @@
-<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
-<html>
-<head>
-   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-   <meta name="GENERATOR" content="Mozilla/4.79 [en] (Windows NT 5.0; U) [Netscape]">
-   <meta name="Author" content="Phil Burk">
-   <meta name="Description" content="PortAudio is a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function.">
-   <meta name="KeyWords" content="audio, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,">
-   <title>PortAudio Release Notes</title>
-</head>
-<body>
-&nbsp;
-<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" >
-<tr>
-<td>
-<center>
-<h1>
-PortAudio - Release Notes</h1></center>
-</td>
-</tr>
-</table></center>
-
-<p>Link to <a href="http://www.portaudio.com">PortAudio Home Page</a>
-<h2>
-<b>V18 - 5/6/02</b></h2>
-
-<blockquote>All source code and documentation now under <a href="http://www.portaudio.com/usingcvs.html">CVS</a>.
-<p>Ran most of the code through <a href="http://astyle.sourceforge.net/">AStyle</a>
-to cleanup ragged indentation caused by using different editors. Used this
-command:
-<br><tt>&nbsp;&nbsp; astyle --style=ansi -c -o --convert-tabs --indent-preprocessor
-*.c</tt></blockquote>
-
-<blockquote>Added "pa_common/pa_convert.c" for Mac OS X. Start of new conversion
-utilities.
-<p><b>ASIO</b>
-<ul>
-<li>
-New Pa_ASIO_Adaptor_Init function to init Callback adpatation variables,</li>
-
-<li>
-Cleanup of Pa_ASIO_Callback_Input</li>
-
-<li>
-Break apart device loading to debug random failure in Pa_ASIO_QueryDeviceInfo</li>
-
-<li>
-Deallocate all resources in PaHost_Term for cases where Pa_CloseStream
-is not called properly</li>
-
-<li>
-New Pa_ASIO_loadDriver that calls CoInitialize on each thread on Windows.
-Allows use by multiple threads.</li>
-
-<li>
-Correct error code management in PaHost_Term, removed various compiler
-warning</li>
-
-<li>
-Add Mac includes for &lt;Devices.h> and &lt;Timer.h></li>
-
-<li>
-Pa_ASIO_QueryDeviceInfo bug correction, memory allocation checking, better
-error handling</li>
-</ul>
-<b>Mac OS X</b>
-<ul>
-<li>
-Major cleanup and improvements.</li>
-
-<li>
-Fixed device queries for numChannels and sampleRates,</li>
-
-<li>
-Audio input works if using same CoreAudio device (some HW devices make
-separate CoreAudio devices).</li>
-
-<li>
-Added paInt16, paInt8, format using new "pa_common/pa_convert.c" file.</li>
-
-<li>
-Return error if opened in mono mode cuz not supported.</li>
-
-<li>
-Check for getenv("PA_MIN_LATEWNCY_MSEC") to set latency externally.</li>
-
-<li>
-Use getrusage() instead of gettimeofday() for CPU Load calculation.</li>
-</ul>
-<b>Windows MME</b>
-<ul>
-<li>
-Fixed bug that caused TIMEOUT in Pa_StopStream(). Added check for past_StopSoon()
-in Pa_TimeSlice(). Thanks Julien Maillard.</li>
-
-<li>
-Detect Win XP versus NT, use lower latency.</li>
-
-<li>
-Fix DBUG typo;</li>
-
-<li>
-removed init of CurrentCount which was not compiling on Borland</li>
-
-<li>
-general cleanup, factored streamData alloc and cpu usage initialization</li>
-
-<li>
-stopped counting WAVE_MAPPER when there were no audio cards plugged in</li>
-</ul>
-<b>Windows DirectSound</b>
-<ul>
-<li>
-Detect Win XP and Win 2K properly when determining latency.</li>
-</ul>
-<b>Unix OSS</b>
-<ul>
-<li>
-Use high real-time priority if app is running with root priveledges. Lowers
-latency.</li>
-
-<li>
-Added watch dog thread that prevents real-time thread from hogging CPU
-and hanging the computer.</li>
-
-<li>
-Check error return from read() and write().</li>
-
-<li>
-Check CPU endianness instead of assuming Little Endian.</li>
-</ul>
-</blockquote>
-
-<h2>
-<b>V17 - 10/15/01</b></h2>
-
-<blockquote><b>Unix OSS</b>
-<ul>
-<li>
-Set num channels back to two after device query for ALSA. This fixed a
-bug in V16 that sometimes caused a failure when querying for the sample
-rates. Thanks Stweart Greenhill.</li>
-</ul>
-</blockquote>
-
-<blockquote>
-<h4>
-<b>Macintosh Sound Manager</b></h4>
-
-<ul>
-<li>
-Use NewSndCallBackUPP() for CARBON compatibility.</li>
-</ul>
-</blockquote>
-
-<h2>
-<b>V16 - 9/27/01</b></h2>
-
-<blockquote><b>Added Alpha implementations for ASIO, SGI, and BeOS!</b>
-<br>&nbsp;
-<li>
-CPULoad is now calculated based on the time spent to generate a known number
-of frames. This is more accurate than a simple percentage of real-time.
-Implemented in pa_unix_oss, pa_win_wmme and pa_win_ds.</li>
-
-<li>
-Fix dither and shift for recording PaUInt8 format data.</li>
-
-<li>
-Added "patest_maxsines.c" which tests <tt>Pa_GetCPULoad().</tt></li>
-</blockquote>
-
-<blockquote>
-<h4>
-Windows WMME</h4>
-
-<ul>
-<li>
-sDevicePtrs now allocated using <tt>GlobalAlloc()</tt>. This prevents a
-crash in Pa_Terminate() on Win2000. Thanks Mike Berry for finding this.
-Thanks Mike Berry.</li>
-
-<li>
-Pass process instead of thread to <tt>SetPriorityClass</tt>(). This fixes
-a bug that caused the priority to not be increased. Thanks to Alberto di
-Bene for spotting this.</li>
-</ul>
-
-<h4>
-Windows DirectSound</h4>
-
-<ul>
-<li>
-Casts for compiling with __MWERKS__ CodeWarrior.</li>
-</ul>
-
-<h4>
-UNIX OSS</h4>
-
-<ul>
-<li>
-Derived from Linux OSS implementation.</li>
-
-<li>
-Numerous patches from Heiko Purnhagen, Stephen Brandon, etc.</li>
-
-<li>
-Improved query mechanism which often bailed out unnecessarily.</li>
-
-<li>
-Removed sNumDevices and potential related bugs,</li>
-
-<li>
-Use <tt>getenv("PA_MIN_LATENCY_MSEC")</tt> in code to set desired latency.
-User can set by entering:</li>
-
-<br>&nbsp;&nbsp;&nbsp; <tt>export PA_MIN_LATENCY_MSEC=40</tt></ul>
-
-<h4>
-Macintosh Sound Manager</h4>
-
-<ul>
-<li>
-Pass unused event to WaitNextEvent instead of NULL to prevent Mac OSX crash.
-Thanks Dominic Mazzoni.</li>
-
-<li>
-Use requested number of input channels.</li>
-
-<br>&nbsp;</ul>
-</blockquote>
-
-<h2>
-<b>V15 - 5/29/01</b></h2>
-
-<blockquote>
-<ul>
-<li>
-<b>New Linux OSS Beta</b></li>
-</ul>
-
-<h4>
-Windows WMME</h4>
-
-<ul>
-<li>
-&nbsp;sDevicePtrs now allocated based on sizeof(pointer). Was allocating
-too much space.</li>
-
-<li>
-&nbsp;Check for excessive numbers of channels. Some drivers reported bogus
-numbers.</li>
-
-<li>
-Apply Mike Berry's changes for CodeWarrior on PC including condition including
-of memory.h, and explicit typecasting on memory allocation.</li>
-</ul>
-
-<h4>
-Macintosh Sound Manager</h4>
-
-<ul>
-<li>
-ScanInputDevices was setting sDefaultOutputDeviceID instead of sDefaultInputDeviceID.</li>
-
-<li>
-Device Scan was crashing for anything other than siBadSoundInDevice, but
-some Macs may return other errors! Caused failure to init on some G4s under
-OS9.</li>
-
-<li>
-Fix TIMEOUT in record mode.</li>
-
-<li>
-Change CARBON_COMPATIBLE to TARGET_API_MAC_CARBON</li>
-</ul>
-</blockquote>
-
-<h2>
-<b>V14 - 2/6/01</b></h2>
-
-<blockquote>
-<ul>
-<li>
-Added implementation for Windows MultiMedia Extensions (WMME) by Ross and
-Phil</li>
-
-<li>
-Changed Pa_StopStream() so that it waits for the buffers to drain.</li>
-
-<li>
-Added Pa_AbortStream() that stops immediately without waiting.</li>
-
-<li>
-Added new test: patest_stop.c to test above two mods.</li>
-
-<li>
-Fixed Pa_StreamTime() so that it returns current play position instead
-of the write position. Added "patest_sync.c" to demo audio/video sync.</li>
-
-<li>
-Improved stability of Macintosh implementation. Added timeouts to prevent
-hangs.</li>
-
-<li>
-Added Pa_GetSampleSize( PaSampleFormat format );</li>
-
-<li>
-Changes some "int"s to "long"s so that PA works properly on Macintosh which
-often compiles using 16 bit ints.</li>
-
-<li>
-Added Implementation Guide</li>
-</ul>
-</blockquote>
-
-<h2>
-<b>V12 - 1/9/01</b></h2>
-
-<blockquote>
-<ul>
-<li>
-Mac now scans for and queries all devices. But it does not yet support
-selecting any other than the default device.</li>
-
-<li>
-Blocking I/O calls renamed to separate them from the PortAudio API.</li>
-
-<li>
-Cleaned up indentation problems with tabs versus spaces.</li>
-
-<li>
-Now attempts to correct bogus sample rate info returned from DirectSound
-device queries.</li>
-</ul>
-</blockquote>
-
-</body>
-</html>
diff --git a/docs/style.html b/docs/style.html
deleted file mode 100644 (file)
index 8f0937c..0000000
+++ /dev/null
@@ -1,156 +0,0 @@
-<HTML>
-<HEAD>
-<TITLE>Coding Style Guidelines for PortAudio Implementors</TITLE>
-<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1252">
-<META content="Phil Burk, Ross Bencina" name=Author>
-<META content="coding and design style guide" name=Description>
-<META 
-content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, synthesis, coding, style" 
-name=KeyWords>
-</HEAD>
-<BODY LINK="#0000ff" VLINK="#800080">&nbsp; 
-<CENTER>
-<TABLE bgColor=#fada7a cols=1 width="100%">
-  <TBODY>
-  <TR>
-    <TD>
-      <CENTER>
-      <H1>Coding Style Guidelines for PortAudio Implementors</H1>
-       </CENTER>
-</TD></TR></TBODY></TABLE></CENTER>
-<P><A href="http://www.portaudio.com/">PortAudio Home Page</A></P>
-
-<P>Updated: June 12, 2002 </P>
-
-<H2>Introduction</H2>
-<P>
-This document provides coding guidelines for PortAudio implementors. Some of the guildelines pertain to mechanical style, others to quality of implementation issues. Since the PortAudio code is commonly edited on many different platforms using different editors these guideline should be followed to improve readability and consistency.
-</P>
-
-<H2>PortAudio API Design Guidelines</H2>
-<P>
-The design guidelines of the PortAudio project are stated here
-as some of them apply to implementation as well as to API design.
-</P>
-<ul>
-       <li>
-       Implementation should be possible on all common computer
-       music platforms.
-       </li>
-       <li>
-       Clients of PortAudio should be able to gain efficient, 
-       and ideally optimal use of the audio services
-       on all target platforms.
-       </li>
-       <li>
-       The API should be simple enough to be used by music
-       students with minimal experience in C programming.
-       </li>
-       <li>
-       The API should seek to provide only low-level audio
-       services, and to only support those services directly
-       available on the host platform.
-       </li>
-</ul>
-
-<P>
-Note that the final guideline has been bent with regard to audio 
-sample formats and user buffer sizes - PortAudio can convert between 
-a number of sample formats and can adapt to the user's buffer size requirements.
-</P>
-
-<H2>Formatting Conventions</H2>
-
-<P>
-The following formatting conventions should be adhered to in all PortAudio code:
-</P>
-
-<UL>
-<LI>TABs should not be used in .c and .h files; instead 4 spaces should be used. Makefiles should continue to use TABs since this is required by Make </LI>
-<LI>Line-emd characters will be consistent with the platform on which the source has been checked out of CVS (CVS handles this.)</LI>
-<LI>Brace placement will follow ANSI style, eg:
-<PRE>
-if( aCondition )
-{
-       DoSomething();
-}
-else
-{
-       DoSomethingElse();
-}
-</PRE>
-</LI>
-</UL>
-
-<P>AStyle ( <A HREF="http://astyle.sourceforge.net/">http://astyle.sourceforge.net/</A> ) has been proposed as helpful tool for cleaning code, however we don't intend to use it on an ongoing basis. It is expected that contributors of each implementation will take responsibility for keeping their code clean.</P>
-
-
-<H2>Quality of Implementation Guidelines</H2>
-
-<P>The following coding guidelines should be followed in order to establish a quality baseline for our implementations:</P>
-
-<UL>
-<LI>All code should be written in C++-compatible plain ANSI-C (i.e. no // comments). It has been suggested that all implementations should compile silently with both "gcc -ansi -pedantic -Wall" and "g++ -ansi -pedantic -Wall" </LI>
-<LI>Think of PortAudio as a heavyweight library rather than a lightweight wrapper. Always code defensively. Efficiency is important where it matters (eg in real-time callbacks) but safety is important everywhere. </LI>
-<LI>All parameters passed to PortAudio by the user should be validated, and error codes returned where necessary. All reasonable efforts should be made to minimise the risk of a crash resulting from passing incorrect parameters to PortAudio. </LI>
-<LI>Error handling should be complete. Every host function that can return an error condition should have its status checked. PortAudio may attempt to recover from errors in some cases, but generally error codes should be returned to the client. </LI>
-<LI>In almost all cases, a PortAudio error code should be preferred to returning PaHostError. If a new PortAudio error code is needed it should be discussed with the maintainer to coordinate updating portaudio.h </LI>
-<LI>PortAudio code should not cause resource leaks. After Pa_Terminate() is called, implementations should guarantee that all dynamically allocated resources have been freed. </LI>
-<LI>The definition of the PortAudio API should minimise "implementation defined behaviour". For example, calling functions such as Pa_Initialize() after PortAudio is initialised, or Pa_Terminate() after PortAudio has been terminated has well defined behaviour.</LI>
-<LI>Minimise dependence on ANSI C runtime on platforms where it would have to be loaded separately (eg on Win32 prefer Win32 API functions such as GlobalAlloc() to ANSI C functions such as malloc().) <I></LI></UL>
-
-</I><P>It has been suggested that we make an effort to minimise the use of global and static data in PortAudio implementations. Another related goal is to reduce name pollution in the global scope. Some possible guidelines in this regard are:</P>
-
-<UL>
-<LI>Implementations should avoid exporting any symbols except where absolutely necessary. Specifically, global data must be declared statically. The next section documents naming conventions for all PortAudio symbols.</LI>
-<LI>Implementations should minimise their use of static data. </LI></UL>
-
-<H2>Naming Conventions</H2>
-
-<ul>
-<li>All #defines begin with PA_</li>
-<li>All #defines local to a file end with _</li>
-<li>All global utility variables begin with paUtil</li>
-<li>All global utility types begin with PaUtil  (including function types)</li>
-<li>All global utility functions begin with PaUtil_</li>
-<li>All static variables end with _</li>
-<li>All static constants begin with const and end with _ (eg: constMyMagicNumber_)</li>
-<li>All static funtions have no special prefix/suffix</li>
-<li>
-Platform-specific shared functions should begin with Pa<PN>_ where PN is the
-platform name. eg. PaWin_ for windows, PaUnix_ for unix.
-</li>
-</ul>
-
-<p>
-In general, implementations should declare all of their members static,
-except for their initializer which should be exported. All exported names
-should be preceeded by Pa<MN>_ where <MN> is the module name, for example
-the windows mme initializer should be named PaWinMme_Initialize().
-</p>
-
-<p>
-If it is necessary for implementations to define non-static symbols, they should
-use the following naming conventions, where <MN> is the module name such as WinMme.
-</p>
-
-<ul>
-<li>global variables should begin with pa<MN></li>
-<li>global types should begin with Pa<MN></li>
-<li>global utility functions should begin with Pa<MN>_</li>
-</ul>
-
-<p>
-Two utilities for debug messages are provided. The PA_DEBUG macro defined in
-pa_implementation.h provides a simple way to print debug messages to stderr.
-Due to real-time performance issues, PA_DEBUG may not be suitable for use
-within the portaudio processing callback, or in other threads. In such cases
-the event tracing facility provided in pa_trace.h may be more appropriate.
-</p>
-<p>
-If PA_LOG_API_CALLS is defined, all calls to the public PortAudio API
-will be logged to stderr along with parameter and return values.
-</p>
-
-</BODY>
-</HTML>
\ No newline at end of file
diff --git a/fixfile.bat b/fixfile.bat
deleted file mode 100755 (executable)
index 48f6fbc..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-rem Use Astyle to fix style in a file
-fixlines -p %1%
-astyle --style=ansi -c -o --convert-tabs --indent-preprocessor %1%
-del %1%.orig
-@rem convert line terminators to Unix style LFs
-fixlines -u %1%
-del %1%.bak
diff --git a/index.html b/index.html
deleted file mode 100644 (file)
index 91e5b4c..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
-<html>
-<head>
-   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-   <meta name="GENERATOR" content="Mozilla/4.79 [en] (Windows NT 5.0; U) [Netscape]">
-   <meta name="Author" content="Phil Burk">
-   <meta name="Description" content="PortAudio is a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function.">
-   <meta name="KeyWords" content="audio, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,">
-   <title>PortAudio Implementations for DirectSound</title>
-</head>
-<body>
-&nbsp;
-<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" >
-<tr>
-<td>
-<center>
-<h1>
-PortAudio - Portable Audio Library</h1></center>
-</td>
-</tr>
-</table></center>
-
-<p>Last updated 5/6/02.
-<p>PortAudio is a cross platform, <a href="#License">open-source</a>, audio
-I/O library proposed by <b>Ross Bencina</b> to the <a href="http://shoko.calarts.edu/~glmrboy/musicdsp/music-dsp.html">music-dsp</a>
-mailing list. It lets you write simple audio programs in 'C' that will
-compile and run on <b>Windows, Macintosh, Unix, BeOS</b>. PortAudio is
-intended to promote the exchange of audio synthesis software between developers
-on different platforms.
-<p>For complete information on PortAudio and to download the latest releases,
-please visit "<b><font size=+2><a href="http://www.portaudio.com">http://www.portaudio.com</a></font></b>".
-<br>&nbsp;
-<br>&nbsp;
-<center>
-<h2>
-<b><a href="docs/index.html">Click here for Documentation</a></b></h2></center>
-
-<h2>
-<b><font size=+2></font></b></h2>
-
-<h2>
-<b><font size=+2>Contacts and E-Mail List</font></b></h2>
-
-<ul>
-<li>
-If you are using or implementing PortAudio then please join the <b><font size=+1><a href="http://techweb.rfa.org/mailman/listinfo/portaudio">PortAudio
-mail list</a></font><font size=+2> </font></b>generously administered by
-<b>Bill
-Eldridge</b>.</li>
-
-<li>
-If you find bugs in one of these implementations, or have suggestions,
-please e-mail them to <a href="mailto:philburk@softsynth.com">Phil Burk</a>.</li>
-
-<li>
-If you make improvements to the library, please send them to us so we can
-incorporate the improvements.</li>
-</ul>
-
-<h2>
-<a NAME="License"></a>License</h2>
-PortAudio Portable Real-Time Audio Library
-<br>Copyright (c) 1999-2000 Ross Bencina and Phil Burk
-<p>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:
-<ul>
-<li>
-The above copyright notice and this permission notice shall be included
-in all copies or substantial portions of the Software.</li>
-
-<li>
-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.</li>
-</ul>
-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 ON INFRINGEMENT.
-<br>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.
-<br>&nbsp;
-</body>
-</html>
diff --git a/install-sh b/install-sh
deleted file mode 100755 (executable)
index e9de238..0000000
Binary files a/install-sh and /dev/null differ
diff --git a/pa_asio/borland_asio_readme.txt b/pa_asio/borland_asio_readme.txt
deleted file mode 100644 (file)
index 56e472b..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-Steinberg's ASIO 2 SDK will compile but crash on 
-initialization if compiled with a Borland compiler.
-
-The problem is described, and a solution provided on 
-the following page:
-http://www.audiomulch.com/~rossb/code/calliasio
\ No newline at end of file
index a2d7d82b637a903d198b3910fe9f0e41d5d9cdb2..66adf4885559aa9c6d17c13721ae39026e242827 100644 (file)
         08-27-01 Implementation of hostBufferSize < userBufferSize case, better management of the ouput buffer when
                  the stream is stopped : Stephane Letz
         08-28-01 Check the stream pointer for null in bufferSwitchTimeInfo, correct bug in bufferSwitchTimeInfo when 
-                 the stream is stopped : Stephane Letz
+                     the stream is stopped : Stephane Letz
         10-12-01 Correct the PaHost_CalcNumHostBuffers function: computes FramesPerHostBuffer to be the lowest that
-                 respect requested FramesPerUserBuffer and userBuffersPerHostBuffer : Stephane Letz
+                         respect requested FramesPerUserBuffer and userBuffersPerHostBuffer : Stephane Letz
         10-26-01 Management of hostBufferSize and userBufferSize of any size : Stephane Letz
         10-27-01 Improve calculus of hostBufferSize to be multiple or divisor of userBufferSize if possible : Stephane and Phil
         10-29-01 Change MAX_INT32_FP to (2147483520.0f) to prevent roundup to 0x80000000 : Phil Burk
         10-31-01 Clear the ouput buffer and user buffers in PaHost_StartOutput, correct bug in GetFirstMultiple : Stephane Letz 
         11-06-01 Rename functions : Stephane Letz 
         11-08-01 New Pa_ASIO_Adaptor_Init function to init Callback adpatation variables, cleanup of Pa_ASIO_Callback_Input: Stephane Letz 
-        11-29-01 Break apart device loading to debug random failure in Pa_ASIO_QueryDeviceInfo ; Phil Burk
-        01-03-02 Desallocate all resources in PaHost_Term for cases where Pa_CloseStream is not called properly :  Stephane Letz
-        02-01-02 Cleanup, test of multiple-stream opening : Stephane Letz
-        19-02-02 New Pa_ASIO_loadDriver that calls CoInitialize on each thread on Windows : Stephane Letz
-        09-04-02 Correct error code management in PaHost_Term, removes various compiler warning : Stephane Letz
-        12-04-02 Add Mac includes for <Devices.h> and <Timer.h> : Phil Burk
-        13-04-02 Removes another compiler warning : Stephane Letz
-        30-04-02 Pa_ASIO_QueryDeviceInfo bug correction, memory allocation checking, better error handling : D Viens, P Burk, S Letz
+               11-29-01 Break apart device loading to debug random failure in Pa_ASIO_QueryDeviceInfo ; Phil Burk
+               01-03-02 Desallocate all resources in PaHost_Term for cases where Pa_CloseStream is not called properly :  Stephane Letz
         
         TO DO :
         
         - Check Pa_StopSteam and Pa_AbortStream
         - Optimization for Input only or Ouput only (really necessary ??)
+        - Opening of several streams   
 */
 
 
 #include <stdio.h>
 #include <assert.h>
-#include <string.h>
 
 #include "portaudio.h"
 #include "pa_host.h"
 #include "asio.h"
 #include "asiodrivers.h"
 
-
 #if MAC
-#include <Devices.h>
-#include <Timer.h>
 #include <Math64.h>
 #else
 #include <math.h>
@@ -176,6 +167,16 @@ typedef struct PaHostSoundControl
 
 
 //----------------------------------------------------------
+// name of the ASIO device to be used
+#if WINDOWS
+        //#define ASIO_DRIVER_NAME    "ASIO Multimedia Driver"
+        #define ASIO_DRIVER_NAME    "ASIO Sample"
+#elif MAC
+        //#define ASIO_DRIVER_NAME      "Apple Sound Manager"
+        #define ASIO_DRIVER_NAME                "ASIO Delta1010"
+        //#define ASIO_DRIVER_NAME      "DigiDesign DirectIO"
+#endif
+
 #define PRINT(x) { printf x; fflush(stdout); }
 #define ERR_RPT(x) PRINT(x)
 
@@ -218,51 +219,51 @@ static bool swap = false;
 #endif
 
 // Prototypes
-static void bufferSwitch(long index, ASIOBool processNow);
-static ASIOTime *bufferSwitchTimeInfo(ASIOTime *timeInfo, long index, ASIOBool processNow);
-static void sampleRateChanged(ASIOSampleRate sRate);
-static long asioMessages(long selector, long value, void* message, double* opt);
+void bufferSwitch(long index, ASIOBool processNow);
+ASIOTime *bufferSwitchTimeInfo(ASIOTime *timeInfo, long index, ASIOBool processNow);
+void sampleRateChanged(ASIOSampleRate sRate);
+long asioMessages(long selector, long value, void* message, double* opt);
 static void Pa_StartUsageCalculation( internalPortAudioStream   *past );
 static void Pa_EndUsageCalculation( internalPortAudioStream   *past );
 
-static void Pa_ASIO_Convert_Inter_Input(
+void Pa_ASIO_Convert_Inter_Input(
         ASIOBufferInfo* nativeBuffer, 
         void* inputBuffer,
-        long NumInputChannels, 
-        long NumOuputChannels,
-        long framePerBuffer,
-        long hostFrameOffset,
-        long userFrameOffset,
+        short NumInputChannels, 
+        short NumOuputChannels,
+        short framePerBuffer,
+        short hostFrameOffset,
+        short userFrameOffset,
         ASIOSampleType nativeFormat, 
         PaSampleFormat paFormat, 
         PaStreamFlags flags,
-        long index);
+        short index);
 
-static void Pa_ASIO_Convert_Inter_Output(
+void Pa_ASIO_Convert_Inter_Output(
         ASIOBufferInfo* nativeBuffer, 
         void* outputBuffer,
-        long NumInputChannels, 
-        long NumOuputChannels,
-        long framePerBuffer,
-        long hostFrameOffset,
-        long userFrameOffset,
+        short NumInputChannels, 
+        short NumOuputChannels,
+        short framePerBuffer,
+        short hostFrameOffset,
+        short userFrameOffset,
         ASIOSampleType nativeFormat, 
         PaSampleFormat paFormat, 
         PaStreamFlags flags,
-        long index);
+        short index);
 
-static void Pa_ASIO_Clear_Output(ASIOBufferInfo* nativeBuffer, 
+ void Pa_ASIO_Clear_Output(ASIOBufferInfo* nativeBuffer, 
         ASIOSampleType nativeFormat,
-        long NumInputChannels, 
-        long NumOuputChannels,
-        long index, 
-        long hostFrameOffset, 
-        long frames);
+        short NumInputChannels, 
+        short NumOuputChannels,
+        int index, 
+        int hostFrameOffset, 
+        int frames);
 
-static void Pa_ASIO_Callback_Input(long index);
-static void Pa_ASIO_Callback_Output(long index, long framePerBuffer);
-static void Pa_ASIO_Callback_End();
-static void Pa_ASIO_Clear_User_Buffers();
+void Pa_ASIO_Callback_Input(long index);
+void Pa_ASIO_Callback_Output(long index, long framePerBuffer);
+void Pa_ASIO_Callback_End();
+void Pa_ASIO_Clear_User_Buffers();
 
 // Some external references
 extern AsioDrivers* asioDrivers ;
@@ -270,6 +271,34 @@ bool loadAsioDriver(char *name);
 unsigned long get_sys_reference_time();
 
 
+// For callback debugging on Mac : to be removed in the final version
+
+/*
+#define MidiSharePPC_68k
+#include <MidiShare.h>
+
+void SendVal (long val)
+{
+        MidiEvPtr ev = MidiNewEv(typeTempo);
+        if (ev) {
+                Tempo(ev) = val;
+                MidiSendIm(0,ev);
+        }
+}
+
+void MidiPrintText ( char * s)
+{
+        MidiEvPtr e;
+        long c = 0;
+
+        if (e = MidiNewEv(typeTextual)){
+                for (c = 0 ; *s ; s++,c++) MidiAddField (e ,*s);
+                MidiSendIm (0, e);
+        }
+}
+*/
+
+
 /************************************************************************************/
 /****************** Macro  ************************************************************/
 /************************************************************************************/
@@ -290,22 +319,12 @@ unsigned long get_sys_reference_time();
 #endif
 
 
-static bool Pa_ASIO_loadAsioDriver(char *name)
-{
-       #ifdef  WINDOWS
-               CoInitialize(0);
-       #endif
-       return loadAsioDriver(name);
-}
-
-
 // Utilities for alignement buffer size computation
-static int PGCD (int a, int b) {return (b == 0) ? a : PGCD (b,a%b);}
-static int PPCM (int a, int b) {return (a*b) / PGCD (a,b);}
+int PGCD (int a, int b) {return (b == 0) ? a : PGCD (b,a%b);}
+int PPCM (int a, int b) {return (a*b) / PGCD (a,b);}
 
 // Takes the size of host buffer and user buffer : returns the number of frames needed for buffer alignement
-static int Pa_ASIO_CalcFrameShift (int M, int N)
+int Pa_ASIO_CalcFrameShift (int M, int N)
 {
         int res = 0;
         for (int i = M; i < PPCM (M,N) ; i+=M) { res = max (res, i%N); }
@@ -433,16 +452,12 @@ static PaError Pa_ASIO_QueryDeviceInfo( internalPortAudioDevice * ipad )
         int           i;
         int           numDrivers;
                ASIOError     asioError;
-               
-          /* Allocate names */
-        for (i = 0 ; i < PA_MAX_DEVICE_INFO ; i++) {
-               names[i] = (char*)PaHost_AllocateFastMemory(32);
-               /* check memory */
-               if(!names[i]) return paInsufficientMemory;
-        }
+        
+        /* Allocate names */
+        for (i = 0 ; i < PA_MAX_DEVICE_INFO ; i++) names[i] = (char*)PaHost_AllocateFastMemory(32);
         
         /* MUST BE CHECKED : to force fragments loading on Mac */
-        Pa_ASIO_loadAsioDriver("dummy");
+        loadAsioDriver("dummy");
         
         /* Get names of all available ASIO drivers */
         asioDrivers->getDriverNames(names,PA_MAX_DEVICE_INFO);
@@ -464,7 +479,7 @@ static PaError Pa_ASIO_QueryDeviceInfo( internalPortAudioDevice * ipad )
             #endif
   
             /* If the driver can be loaded : */
-            if ( !Pa_ASIO_loadAsioDriver(names[driver]) )
+            if ( !loadAsioDriver(names[driver]) )
                        {
                                DBUG(("PaASIO_QueryDeviceInfo could not loadAsioDriver %s\n", names[driver]));
                        }
@@ -478,8 +493,9 @@ static PaError Pa_ASIO_QueryDeviceInfo( internalPortAudioDevice * ipad )
                        }
                        else
                        {
-                           /* Gets the name */
-                    dev = &(ipad[sNumDevices].pad_Info);
+                                       
+                    /* Gets the name */
+                    dev = &(ipad[driver].pad_Info);
                     dev->name = names[driver];
                     names[driver] = 0;
                     
@@ -491,12 +507,7 @@ static PaError Pa_ASIO_QueryDeviceInfo( internalPortAudioDevice * ipad )
                     DBUG(("PaASIO_QueryDeviceInfo: OutputChannels = %d\n", OutputChannels ));
                     
                     /* Make room in case device supports all rates. */
-                    sampleRates = (double*)PaHost_AllocateFastMemory(MAX_NUMSAMPLINGRATES * sizeof(double));
-                    /* check memory */
-                    if (!sampleRates) {
-                       ASIOExit();
-                       return paInsufficientMemory;
-                    }
+                    sampleRates = (double*)PaHost_AllocateFastMemory( MAX_NUMSAMPLINGRATES * sizeof(double));
                     dev->sampleRates = sampleRates;
                     dev->numSampleRates = 0;
                     
@@ -504,7 +515,7 @@ static PaError Pa_ASIO_QueryDeviceInfo( internalPortAudioDevice * ipad )
                     for (int index = 0; index < MAX_NUMSAMPLINGRATES; index++) {
                             if (ASIOCanSampleRate(possibleSampleRates[index]) != ASE_NoClock) {
                                     DBUG(("PortAudio : possible sample rate = %d\n", (long)possibleSampleRates[index]));
-                                    dev->numSampleRates += 1;
+                                    dev->numSampleRates+=1;
                                     *sampleRates = possibleSampleRates[index];
                                     sampleRates++;
                             }
@@ -518,7 +529,9 @@ static PaError Pa_ASIO_QueryDeviceInfo( internalPortAudioDevice * ipad )
                     dev->nativeSampleFormats = Pa_ASIO_Convert_SampleFormat(channelInfos.type);
                     
                     /* unload the driver */
+                    ASIODisposeBuffers();
                     ASIOExit();
+                    
                     sNumDevices++;
                 }
         }       
@@ -531,7 +544,7 @@ static PaError Pa_ASIO_QueryDeviceInfo( internalPortAudioDevice * ipad )
 
 //----------------------------------------------------------------------------------
 // TAKEN FROM THE ASIO SDK: 
-static void sampleRateChanged(ASIOSampleRate sRate)
+void sampleRateChanged(ASIOSampleRate sRate)
 {
         // do whatever you need to do if the sample rate changed
         // usually this only happens during external sync.
@@ -623,13 +636,13 @@ long asioMessages(long selector, long value, void* message, double* opt)
 #endif
 
 
-static ASIOTime *bufferSwitchTimeInfo(ASIOTime *timeInfo, long index, ASIOBool processNow)
+ASIOTime *bufferSwitchTimeInfo(ASIOTime *timeInfo, long index, ASIOBool processNow)
 {       
         // the actual processing callback.
         // Beware that this is normally in a seperate thread, hence be sure that you take care
         // about thread synchronization. This is omitted here for simplicity.
         
-       // static processedSamples = 0;
+        static processedSamples = 0;
         int  result = 0;
         
         // store the timeInfo for later use
@@ -737,7 +750,7 @@ unsigned long get_sys_reference_time()
         // get the system reference time
         #if WINDOWS
                 return timeGetTime();
-            #elif MAC
+        #elif MAC
                 static const double twoRaisedTo32 = 4294967296.;
                 UnsignedWide ys;
                 Microseconds(&ys);
@@ -773,7 +786,7 @@ inline static long Pa_TriangularDither( void )
 // TO BE COMPLETED WITH ALL SUPPORTED PA SAMPLE TYPES
 
 //-------------------------------------------------------------------------------------------------------------------------------------------------------
-static void Input_Int16_Float32 (ASIOBufferInfo* nativeBuffer, float *inBufPtr, int framePerBuffer, int NumInputChannels, int index, int hostFrameOffset,int userFrameOffset, bool swap)
+ void Input_Int16_Flot32 (ASIOBufferInfo* nativeBuffer, float *inBufPtr, int framePerBuffer, int NumInputChannels, int index, int hostFrameOffset,int userFrameOffset, bool swap)
 {
         long temp;
         int i,j;
@@ -793,7 +806,7 @@ static void Input_Int16_Float32 (ASIOBufferInfo* nativeBuffer, float *inBufPtr,
 }
 
 //-------------------------------------------------------------------------------------------------------------------------------------------------------
-static void Input_Int32_Float32 (ASIOBufferInfo* nativeBuffer, float *inBufPtr, int framePerBuffer, int NumInputChannels, int index, int hostFrameOffset,int userFrameOffset,bool swap)
+ void Input_Int32_Flot32 (ASIOBufferInfo* nativeBuffer, float *inBufPtr, int framePerBuffer, int NumInputChannels, int index, int hostFrameOffset,int userFrameOffset,bool swap)
 {
         long temp;
         int i,j;
@@ -813,17 +826,17 @@ static void Input_Int32_Float32 (ASIOBufferInfo* nativeBuffer, float *inBufPtr,
 
 //-------------------------------------------------------------------------------------------------------------------------------------------------------
 // MUST BE TESTED
-static void Input_Float32_Float32 (ASIOBufferInfo* nativeBuffer, float *inBufPtr, int framePerBuffer, int NumInputChannels, int index, int hostFrameOffset,int userFrameOffset,bool swap)
+ void Input_Float32_Flot32 (ASIOBufferInfo* nativeBuffer, float *inBufPtr, int framePerBuffer, int NumInputChannels, int index, int hostFrameOffset,int userFrameOffset,bool swap)
 {
-        unsigned long temp;
+        long temp;
         int i,j;
         
         for( j=0; j<NumInputChannels; j++ ) {
-                unsigned long *asioBufPtr = &((unsigned long*)nativeBuffer[j].buffers[index])[hostFrameOffset];
+                float *asioBufPtr = &((float*)nativeBuffer[j].buffers[index])[hostFrameOffset];
                 float *userBufPtr = &inBufPtr[j+(userFrameOffset*NumInputChannels)];
                 for (i= 0; i < framePerBuffer; i++)
                 { 
-                        temp = asioBufPtr[i];
+                        temp = (long)asioBufPtr[i];
                         if (swap) temp = SwapLong(temp);
                         *userBufPtr = (float)temp;
                         userBufPtr += NumInputChannels;
@@ -832,7 +845,7 @@ static void Input_Float32_Float32 (ASIOBufferInfo* nativeBuffer, float *inBufPtr
 }
 
 //-------------------------------------------------------------------------------------------------------------------------------------------------------
-static  void Input_Int16_Int32 (ASIOBufferInfo* nativeBuffer, long *inBufPtr, int framePerBuffer, int NumInputChannels, int index, int hostFrameOffset,int userFrameOffset,bool swap)
+ void Input_Int16_Int32 (ASIOBufferInfo* nativeBuffer, long *inBufPtr, int framePerBuffer, int NumInputChannels, int index, int hostFrameOffset,int userFrameOffset,bool swap)
 {
         long temp;
         int i,j;
@@ -851,7 +864,7 @@ static  void Input_Int16_Int32 (ASIOBufferInfo* nativeBuffer, long *inBufPtr, in
 }
 
 //-------------------------------------------------------------------------------------------------------------------------------------------------------
-static  void Input_Int32_Int32 (ASIOBufferInfo* nativeBuffer, long *inBufPtr, int framePerBuffer, int NumInputChannels, int index, int hostFrameOffset,int userFrameOffset,bool swap)
+ void Input_Int32_Int32 (ASIOBufferInfo* nativeBuffer, long *inBufPtr, int framePerBuffer, int NumInputChannels, int index, int hostFrameOffset,int userFrameOffset,bool swap)
 {
         long temp;
         int i,j;
@@ -871,17 +884,17 @@ static  void Input_Int32_Int32 (ASIOBufferInfo* nativeBuffer, long *inBufPtr, in
 
 //-------------------------------------------------------------------------------------------------------------------------------------------------------
 // MUST BE TESTED
-static  void Input_Float32_Int32 (ASIOBufferInfo* nativeBuffer, long *inBufPtr, int framePerBuffer, int NumInputChannels, int index, int hostFrameOffset,int userFrameOffset,bool swap)
+ void Input_Float32_Int32 (ASIOBufferInfo* nativeBuffer, long *inBufPtr, int framePerBuffer, int NumInputChannels, int index, int hostFrameOffset,int userFrameOffset,bool swap)
 {
-        unsigned long temp;
+        long temp;
         int i,j;
 
         for( j=0; j<NumInputChannels; j++ ) {
-                unsigned long *asioBufPtr = &((unsigned long*)nativeBuffer[j].buffers[index])[hostFrameOffset];
+                float *asioBufPtr = &((float*)nativeBuffer[j].buffers[index])[hostFrameOffset];
                 long *userBufPtr = &inBufPtr[j+(userFrameOffset*NumInputChannels)];
                 for (i= 0; i < framePerBuffer; i++)
                 { 
-                        temp = asioBufPtr[i];
+                        temp = (long) asioBufPtr[i];
                         if (swap) temp = SwapLong(temp);
                         *userBufPtr = (long)((float)temp * MAX_INT32_FP); // Is temp a value between -1.0 and 1.0 ??
                         userBufPtr += NumInputChannels;
@@ -891,7 +904,7 @@ static  void Input_Float32_Int32 (ASIOBufferInfo* nativeBuffer, long *inBufPtr,
 
 
 //-------------------------------------------------------------------------------------------------------------------------------------------------------
-static  void Input_Int16_Int16 (ASIOBufferInfo* nativeBuffer, short *inBufPtr, int framePerBuffer, int NumInputChannels, int index, int hostFrameOffset,int userFrameOffset,bool swap)
+ void Input_Int16_Int16 (ASIOBufferInfo* nativeBuffer, short *inBufPtr, int framePerBuffer, int NumInputChannels, int index, int hostFrameOffset,int userFrameOffset,bool swap)
 {
         long temp;
         int i,j;
@@ -903,14 +916,14 @@ static  void Input_Int16_Int16 (ASIOBufferInfo* nativeBuffer, short *inBufPtr, i
                 { 
                         temp = asioBufPtr[i];
                         if (swap) temp = SwapShort(temp);
-                        *userBufPtr = (short)temp;
+                        *userBufPtr = temp;
                         userBufPtr += NumInputChannels;
                 }
         }
 }
  
  //-------------------------------------------------------------------------------------------------------------------------------------------------------
-static  void Input_Int32_Int16 (ASIOBufferInfo* nativeBuffer, short *inBufPtr, int framePerBuffer, int NumInputChannels, int index, int hostFrameOffset, int userFrameOffset,uint32 flags,bool swap)
+ void Input_Int32_Int16 (ASIOBufferInfo* nativeBuffer, short *inBufPtr, int framePerBuffer, int NumInputChannels, int index, int hostFrameOffset, int userFrameOffset,uint32 flags,bool swap)
 {
         long temp;
         int i,j;
@@ -924,7 +937,7 @@ static  void Input_Int32_Int16 (ASIOBufferInfo* nativeBuffer, short *inBufPtr, i
                         { 
                                 temp = asioBufPtr[i];
                                 if (swap) temp = SwapLong(temp);
-                                *userBufPtr = (short)(temp>>16);
+                                *userBufPtr = temp>>16;
                                 userBufPtr += NumInputChannels;
                         }
                 }
@@ -941,7 +954,7 @@ static  void Input_Int32_Int16 (ASIOBufferInfo* nativeBuffer, short *inBufPtr, i
                                 temp = (temp >> 1) + Pa_TriangularDither();
                                 temp = temp >> 15;
                                 temp = (short) ClipShort(temp);
-                                *userBufPtr = (short)temp;
+                                *userBufPtr = temp;
                                 userBufPtr += NumInputChannels;
                         }
                 }
@@ -951,19 +964,19 @@ static  void Input_Int32_Int16 (ASIOBufferInfo* nativeBuffer, short *inBufPtr, i
 
 //-------------------------------------------------------------------------------------------------------------------------------------------------------
 // MUST BE TESTED
-static void Input_Float32_Int16 (ASIOBufferInfo* nativeBuffer, short *inBufPtr, int framePerBuffer, int NumInputChannels, int index, int hostFrameOffset,int userFrameOffset,uint32 flags,bool swap)
+ void Input_Float32_Int16 (ASIOBufferInfo* nativeBuffer, short *inBufPtr, int framePerBuffer, int NumInputChannels, int index, int hostFrameOffset,int userFrameOffset,uint32 flags,bool swap)
 {
-        unsigned long temp;
+        long temp;
         int i,j;
         
         if( flags & paDitherOff )
         {
                 for( j=0; j<NumInputChannels; j++ ) {
-                        unsigned long *asioBufPtr = &((unsigned long*)nativeBuffer[j].buffers[index])[hostFrameOffset];
+                        float *asioBufPtr = &((float*)nativeBuffer[j].buffers[index])[hostFrameOffset];
                         short *userBufPtr = &inBufPtr[j+(userFrameOffset*NumInputChannels)];
                         for (i= 0; i < framePerBuffer; i++)
                         { 
-                                temp = asioBufPtr[i];
+                                temp = (long)asioBufPtr[i];
                                 if (swap) temp = SwapLong(temp);
                                 *userBufPtr = (short)((float)temp * MAX_INT16_FP); // Is temp a value between -1.0 and 1.0 ??
                                 userBufPtr += NumInputChannels;
@@ -973,16 +986,16 @@ static void Input_Float32_Int16 (ASIOBufferInfo* nativeBuffer, short *inBufPtr,
         else
         {
                 for( j=0; j<NumInputChannels; j++ ) {
-                        unsigned long *asioBufPtr = &((unsigned long*)nativeBuffer[j].buffers[index])[hostFrameOffset];
+                        float *asioBufPtr = &((float*)nativeBuffer[j].buffers[index])[hostFrameOffset];
                         short *userBufPtr = &inBufPtr[j+(userFrameOffset*NumInputChannels)];
                         for (i= 0; i < framePerBuffer; i++)
                         { 
                                 float dither  = Pa_TriangularDither()*DITHER_SCALE;
-                                temp = asioBufPtr[i];
+                                temp = (long)asioBufPtr[i];
                                 if (swap) temp = SwapLong(temp);
                                 temp = (short)(((float)temp * MAX_INT16_FP) + dither);
                                 temp = ClipShort(temp);
-                                *userBufPtr = (short)temp;
+                                *userBufPtr = temp;
                                 userBufPtr += NumInputChannels;
                         }
                 }
@@ -990,7 +1003,7 @@ static void Input_Float32_Int16 (ASIOBufferInfo* nativeBuffer, short *inBufPtr,
 }
 
 //-------------------------------------------------------------------------------------------------------------------------------------------------------
-static void Input_Int16_Int8 (ASIOBufferInfo* nativeBuffer, char *inBufPtr, int framePerBuffer, int NumInputChannels, int index, int hostFrameOffset,int userFrameOffset, uint32 flags,bool swap)
+ void Input_Int16_Int8 (ASIOBufferInfo* nativeBuffer, char *inBufPtr, int framePerBuffer, int NumInputChannels, int index, int hostFrameOffset,int userFrameOffset, uint32 flags,bool swap)
 {
         long temp;
         int i,j;
@@ -1028,7 +1041,7 @@ static void Input_Int16_Int8 (ASIOBufferInfo* nativeBuffer, char *inBufPtr, int
 }
 
 //-------------------------------------------------------------------------------------------------------------------------------------------------------
-static void Input_Int32_Int8 (ASIOBufferInfo* nativeBuffer, char *inBufPtr, int framePerBuffer, int NumInputChannels, int index, int hostFrameOffset, int userFrameOffset, uint32 flags,bool swap)
+ void Input_Int32_Int8 (ASIOBufferInfo* nativeBuffer, char *inBufPtr, int framePerBuffer, int NumInputChannels, int index, int hostFrameOffset, int userFrameOffset, uint32 flags,bool swap)
 {
         long temp;
         int i,j;
@@ -1069,15 +1082,15 @@ static void Input_Int32_Int8 (ASIOBufferInfo* nativeBuffer, char *inBufPtr, int
 //-------------------------------------------------------------------------------------------------------------------------------------------------------
 // MUST BE TESTED
 
-static void Input_Float32_Int8 (ASIOBufferInfo* nativeBuffer, char *inBufPtr, int framePerBuffer, int NumInputChannels, int index, int hostFrameOffset,int userFrameOffset,  uint32 flags,bool swap)
+ void Input_Float32_Int8 (ASIOBufferInfo* nativeBuffer, char *inBufPtr, int framePerBuffer, int NumInputChannels, int index, int hostFrameOffset,int userFrameOffset,  uint32 flags,bool swap)
 {
-        unsigned long temp;
+        long temp;
         int i,j;
         
         if( flags & paDitherOff )
         {
                 for( j=0; j<NumInputChannels; j++ ) {
-                        unsigned long *asioBufPtr = &((unsigned long*)nativeBuffer[j].buffers[index])[hostFrameOffset];
+                        long *asioBufPtr = &((long*)nativeBuffer[j].buffers[index])[hostFrameOffset];
                         char *userBufPtr = &inBufPtr[j+(userFrameOffset*NumInputChannels)];
                         for (i= 0; i < framePerBuffer; i++)
                         { 
@@ -1091,7 +1104,7 @@ static void Input_Float32_Int8 (ASIOBufferInfo* nativeBuffer, char *inBufPtr, in
         else
         {
                 for( j=0; j<NumInputChannels; j++ ) {
-                        unsigned long *asioBufPtr = &((unsigned long*)nativeBuffer[j].buffers[index])[hostFrameOffset];
+                        long *asioBufPtr = &((long*)nativeBuffer[j].buffers[index])[hostFrameOffset];
                         char *userBufPtr = &inBufPtr[j+(userFrameOffset*NumInputChannels)];
                         for (i= 0; i < framePerBuffer; i++)
                         { 
@@ -1100,7 +1113,7 @@ static void Input_Float32_Int8 (ASIOBufferInfo* nativeBuffer, char *inBufPtr, in
                                 if (swap) temp = SwapLong(temp);
                                 temp = (char)(((float)temp * MAX_INT8_FP) + dither);
                                 temp = ClipChar(temp);
-                                *userBufPtr = (char)temp;
+                                *userBufPtr = temp ;
                                 userBufPtr += NumInputChannels;
                         }
                 }
@@ -1108,7 +1121,7 @@ static void Input_Float32_Int8 (ASIOBufferInfo* nativeBuffer, char *inBufPtr, in
 }
 
 //-------------------------------------------------------------------------------------------------------------------------------------------------------
-static void Input_Int16_IntU8 (ASIOBufferInfo* nativeBuffer, unsigned char *inBufPtr, int framePerBuffer, int NumInputChannels, int index, int hostFrameOffset,int userFrameOffset, uint32 flags,bool swap)
+ void Input_Int16_IntU8 (ASIOBufferInfo* nativeBuffer, unsigned char *inBufPtr, int framePerBuffer, int NumInputChannels, int index, int hostFrameOffset,int userFrameOffset, uint32 flags,bool swap)
 {
         long temp;
         int i,j;
@@ -1146,7 +1159,7 @@ static void Input_Int16_IntU8 (ASIOBufferInfo* nativeBuffer, unsigned char *inBu
 }
 
 //-------------------------------------------------------------------------------------------------------------------------------------------------------
-static void Input_Int32_IntU8 (ASIOBufferInfo* nativeBuffer, unsigned char *inBufPtr, int framePerBuffer, int NumInputChannels, int index, int hostFrameOffset, int userFrameOffset,uint32 flags,bool swap)
+ void Input_Int32_IntU8 (ASIOBufferInfo* nativeBuffer, unsigned char *inBufPtr, int framePerBuffer, int NumInputChannels, int index, int hostFrameOffset, int userFrameOffset,uint32 flags,bool swap)
 {
         long temp;
         int i,j;
@@ -1187,19 +1200,19 @@ static void Input_Int32_IntU8 (ASIOBufferInfo* nativeBuffer, unsigned char *inBu
 //-------------------------------------------------------------------------------------------------------------------------------------------------------
 // MUST BE TESTED
 
-static void Input_Float32_IntU8 (ASIOBufferInfo* nativeBuffer, unsigned char *inBufPtr, int framePerBuffer, int NumInputChannels, int index, int hostFrameOffset,int userFrameOffset, uint32 flags,bool swap)
+ void Input_Float32_IntU8 (ASIOBufferInfo* nativeBuffer, unsigned char *inBufPtr, int framePerBuffer, int NumInputChannels, int index, int hostFrameOffset,int userFrameOffset, uint32 flags,bool swap)
 {
-        unsigned long temp;
+        long temp;
         int i,j;
         
         if( flags & paDitherOff )
         {
                 for( j=0; j<NumInputChannels; j++ ) {
-                        unsigned long *asioBufPtr = &((unsigned long*)nativeBuffer[j].buffers[index])[hostFrameOffset];
+                        float *asioBufPtr = &((float*)nativeBuffer[j].buffers[index])[hostFrameOffset];
                         unsigned char *userBufPtr = &inBufPtr[j+(userFrameOffset*NumInputChannels)];
                         for (i= 0; i < framePerBuffer; i++)
                         { 
-                                temp = asioBufPtr[i];
+                                temp = (float) asioBufPtr[i];
                                 if (swap) temp = SwapLong(temp);
                                 *userBufPtr = (unsigned char)(((float)temp*MAX_INT8_FP) + 0x80);
                                 userBufPtr += NumInputChannels;
@@ -1209,12 +1222,12 @@ static void Input_Float32_IntU8 (ASIOBufferInfo* nativeBuffer, unsigned char *in
         else
         {       
                 for( j=0; j<NumInputChannels; j++ ) {
-                        unsigned long *asioBufPtr = &((unsigned long*)nativeBuffer[j].buffers[index])[hostFrameOffset];
+                        float *asioBufPtr = &((float*)nativeBuffer[j].buffers[index])[hostFrameOffset];
                         unsigned char *userBufPtr = &inBufPtr[j+(userFrameOffset*NumInputChannels)];
                         for (i= 0; i < framePerBuffer; i++)
                         { 
                                 float dither  = Pa_TriangularDither()*DITHER_SCALE;
-                                temp = asioBufPtr[i];
+                                temp = (float) asioBufPtr[i];
                                 if (swap) temp = SwapLong(temp);
                                 temp = (char)(((float)temp * MAX_INT8_FP) + dither);
                                 temp = ClipChar(temp);
@@ -1228,7 +1241,7 @@ static void Input_Float32_IntU8 (ASIOBufferInfo* nativeBuffer, unsigned char *in
                 
 // OUPUT 
 //-------------------------------------------------------------------------------------------------------------------------------------------------------
-static void Output_Float32_Int16 (ASIOBufferInfo* nativeBuffer, float *outBufPtr, int framePerBuffer, int NumInputChannels, int NumOuputChannels, int index, int hostFrameOffset, int userFrameOffset,uint32 flags, bool swap)
+ void Output_Float32_Int16 (ASIOBufferInfo* nativeBuffer, float *outBufPtr, int framePerBuffer, int NumInputChannels, int NumOuputChannels, int index, int hostFrameOffset, int userFrameOffset,uint32 flags, bool swap)
 {
         long temp;
         int i,j;
@@ -1245,7 +1258,7 @@ static void Output_Float32_Int16 (ASIOBufferInfo* nativeBuffer, float *outBufPtr
                                         {
                                                 temp = (short) (*userBufPtr * MAX_INT16_FP);
                                                 if (swap) temp = SwapShort(temp);
-                                                asioBufPtr[i] = (short)temp;
+                                                asioBufPtr[i] = temp;
                                                 userBufPtr += NumOuputChannels;
                                         }
                                 }
@@ -1261,7 +1274,7 @@ static void Output_Float32_Int16 (ASIOBufferInfo* nativeBuffer, float *outBufPtr
                                                 temp = (long) (*userBufPtr * MAX_INT16_FP);
                                                 temp = ClipShort(temp);
                                                 if (swap) temp = SwapShort(temp);
-                                                asioBufPtr[i] = (short)temp;
+                                                asioBufPtr[i] = temp;
                                                 userBufPtr += NumOuputChannels;
                                         }
                                 }
@@ -1271,24 +1284,24 @@ static void Output_Float32_Int16 (ASIOBufferInfo* nativeBuffer, float *outBufPtr
                 {
                         /* If you dither then you have to clip because dithering could push the signal out of range! */
                         for( j=0; j<NumOuputChannels; j++ ) {
-                                short *asioBufPtr = &((short*)nativeBuffer[j+NumInputChannels].buffers[index])[hostFrameOffset];
-                                float *userBufPtr = &outBufPtr[j+(userFrameOffset*NumOuputChannels)];
-                                
-                                for (i= 0; i < framePerBuffer; i++) 
-                                {
-                                        float dither = Pa_TriangularDither()*DITHER_SCALE;
-                                        temp = (long) ((*userBufPtr * MAX_INT16_FP) + dither);
-                                        temp = ClipShort(temp);
-                                        if (swap) temp = SwapShort(temp);
-                                        asioBufPtr[i] = (short)temp;
-                                        userBufPtr += NumOuputChannels;
+                                        short *asioBufPtr = &((short*)nativeBuffer[j+NumInputChannels].buffers[index])[hostFrameOffset];
+                                        float *userBufPtr = &outBufPtr[j+(userFrameOffset*NumOuputChannels)];
+                                        
+                                        for (i= 0; i < framePerBuffer; i++) 
+                                        {
+                                                float dither = Pa_TriangularDither()*DITHER_SCALE;
+                                                temp = (long) ((*userBufPtr * MAX_INT16_FP) + dither);
+                                                temp = ClipShort(temp);
+                                                if (swap) temp = SwapShort(temp);
+                                                asioBufPtr[i] = temp;
+                                                userBufPtr += NumOuputChannels;
+                                        }
                                 }
-                        }
                 }
 }
 
 //-------------------------------------------------------------------------------------------------------------------------------------------------------
-static void Output_Float32_Int32 (ASIOBufferInfo* nativeBuffer, float *outBufPtr, int framePerBuffer, int NumInputChannels, int NumOuputChannels, int index, int hostFrameOffset, int userFrameOffset,uint32 flags,bool swap)
+ void Output_Float32_Int32 (ASIOBufferInfo* nativeBuffer, float *outBufPtr, int framePerBuffer, int NumInputChannels, int NumOuputChannels, int index, int hostFrameOffset, int userFrameOffset,uint32 flags,bool swap)
 {
         long temp;
         int i,j;
@@ -1332,7 +1345,7 @@ static void Output_Float32_Int32 (ASIOBufferInfo* nativeBuffer, float *outBufPtr
 //-------------------------------------------------------------------------------------------------------------------------------------------------------
 // MUST BE TESTED
 
static void Output_Float32_Float32 (ASIOBufferInfo* nativeBuffer, float *outBufPtr, int framePerBuffer, int NumInputChannels, int NumOuputChannels, int index, int hostFrameOffset, int userFrameOffset,uint32 flags,bool swap)
+ void Output_Float32_Float32 (ASIOBufferInfo* nativeBuffer, float *outBufPtr, int framePerBuffer, int NumInputChannels, int NumOuputChannels, int index, int hostFrameOffset, int userFrameOffset,uint32 flags,bool swap)
 {
         long temp;
         int i,j;
@@ -1372,9 +1385,8 @@ static void Output_Float32_Int32 (ASIOBufferInfo* nativeBuffer, float *outBufPtr
         }
         
 }
-
 //-------------------------------------------------------------------------------------------------------------------------------------------------------                                       
-static void Output_Int32_Int16(ASIOBufferInfo* nativeBuffer, long *outBufPtr, int framePerBuffer, int NumInputChannels, int NumOuputChannels, int index, int hostFrameOffset,int userFrameOffset,uint32 flags,bool swap)
+ void Output_Int32_Int16(ASIOBufferInfo* nativeBuffer, long *outBufPtr, int framePerBuffer, int NumInputChannels, int NumOuputChannels, int index, int hostFrameOffset,int userFrameOffset,uint32 flags,bool swap)
 {
         long temp;
         int i,j;
@@ -1389,7 +1401,7 @@ static void Output_Int32_Int16(ASIOBufferInfo* nativeBuffer, long *outBufPtr, in
                         {
                                 temp = (short) ((*userBufPtr) >> 16);
                                 if (swap) temp = SwapShort(temp);
-                                asioBufPtr[i] = (short)temp;
+                                asioBufPtr[i] = temp;
                                 userBufPtr += NumOuputChannels;
                         }
                 }
@@ -1406,7 +1418,7 @@ static void Output_Int32_Int16(ASIOBufferInfo* nativeBuffer, long *outBufPtr, in
                                 temp = temp >> 15;
                                 temp = (short) ClipShort(temp);
                                 if (swap) temp = SwapShort(temp);
-                                asioBufPtr[i] = (short)temp;
+                                asioBufPtr[i] = temp;
                                 userBufPtr += NumOuputChannels;
                         }
                 }
@@ -1414,7 +1426,7 @@ static void Output_Int32_Int16(ASIOBufferInfo* nativeBuffer, long *outBufPtr, in
 }
 
 //-------------------------------------------------------------------------------------------------------------------------------------------------------
-static void Output_Int32_Int32(ASIOBufferInfo* nativeBuffer, long *outBufPtr, int framePerBuffer, int NumInputChannels, int NumOuputChannels, int index, int hostFrameOffset,int userFrameOffset,uint32 flags,bool swap)
+ void Output_Int32_Int32(ASIOBufferInfo* nativeBuffer, long *outBufPtr, int framePerBuffer, int NumInputChannels, int NumOuputChannels, int index, int hostFrameOffset,int userFrameOffset,uint32 flags,bool swap)
 {
         long temp;
         int i,j;
@@ -1436,7 +1448,7 @@ static void Output_Int32_Int32(ASIOBufferInfo* nativeBuffer, long *outBufPtr, in
 //-------------------------------------------------------------------------------------------------------------------------------------------------------
 // MUST BE CHECKED
 
-static void Output_Int32_Float32(ASIOBufferInfo* nativeBuffer, long *outBufPtr, int framePerBuffer, int NumInputChannels, int NumOuputChannels, int index, int hostFrameOffset,int userFrameOffset,uint32 flags,bool swap)
+ void Output_Int32_Float32(ASIOBufferInfo* nativeBuffer, long *outBufPtr, int framePerBuffer, int NumInputChannels, int NumOuputChannels, int index, int hostFrameOffset,int userFrameOffset,uint32 flags,bool swap)
 {
         long temp;
         int i,j;
@@ -1456,7 +1468,7 @@ static void Output_Int32_Float32(ASIOBufferInfo* nativeBuffer, long *outBufPtr,
 }
 
 //-------------------------------------------------------------------------------------------------------------------------------------------------------
-static void Output_Int16_Int16(ASIOBufferInfo* nativeBuffer, short *outBufPtr, int framePerBuffer, int NumInputChannels, int NumOuputChannels, int index, int hostFrameOffset, int userFrameOffset,bool swap)
+ void Output_Int16_Int16(ASIOBufferInfo* nativeBuffer, short *outBufPtr, int framePerBuffer, int NumInputChannels, int NumOuputChannels, int index, int hostFrameOffset, int userFrameOffset,bool swap)
 {
         long temp;
         int i,j;
@@ -1469,14 +1481,14 @@ static void Output_Int16_Int16(ASIOBufferInfo* nativeBuffer, short *outBufPtr, i
                 {
                         temp = *userBufPtr;
                         if (swap) temp = SwapShort(temp);
-                        asioBufPtr[i] = (short)temp;
+                        asioBufPtr[i] = temp;
                         userBufPtr += NumOuputChannels;
                 }
         }
 }
 
 //-------------------------------------------------------------------------------------------------------------------------------------------------------
-static void Output_Int16_Int32(ASIOBufferInfo* nativeBuffer, short *outBufPtr, int framePerBuffer, int NumInputChannels, int NumOuputChannels, int index, int hostFrameOffset,int userFrameOffset, bool swap)
+ void Output_Int16_Int32(ASIOBufferInfo* nativeBuffer, short *outBufPtr, int framePerBuffer, int NumInputChannels, int NumOuputChannels, int index, int hostFrameOffset,int userFrameOffset, bool swap)
 {
         long temp;
         int i,j;
@@ -1497,7 +1509,7 @@ static void Output_Int16_Int32(ASIOBufferInfo* nativeBuffer, short *outBufPtr, i
 
 //-------------------------------------------------------------------------------------------------------------------------------------------------------
 // MUST BE CHECKED
-static void Output_Int16_Float32(ASIOBufferInfo* nativeBuffer, short *outBufPtr, int framePerBuffer, int NumInputChannels, int NumOuputChannels, int index, int hostFrameOffset,int userFrameOffset, bool swap)
+ void Output_Int16_Float32(ASIOBufferInfo* nativeBuffer, short *outBufPtr, int framePerBuffer, int NumInputChannels, int NumOuputChannels, int index, int hostFrameOffset,int userFrameOffset, bool swap)
 {
         long temp;
         int i,j;
@@ -1515,7 +1527,7 @@ static void Output_Int16_Float32(ASIOBufferInfo* nativeBuffer, short *outBufPtr,
         }
 }
 //-------------------------------------------------------------------------------------------------------------------------------------------------------
-static void Output_Int8_Int16(ASIOBufferInfo* nativeBuffer, char *outBufPtr, int framePerBuffer, int NumInputChannels, int NumOuputChannels, int index, int hostFrameOffset,int userFrameOffset, bool swap)
+ void Output_Int8_Int16(ASIOBufferInfo* nativeBuffer, char *outBufPtr, int framePerBuffer, int NumInputChannels, int NumOuputChannels, int index, int hostFrameOffset,int userFrameOffset, bool swap)
 {
         long temp;
         int i,j;
@@ -1528,14 +1540,14 @@ static void Output_Int8_Int16(ASIOBufferInfo* nativeBuffer, char *outBufPtr, int
                 {
                         temp = (short)(*userBufPtr)<<8;
                         if (swap) temp = SwapShort(temp);
-                        asioBufPtr[i] = (short)temp;
+                        asioBufPtr[i] = temp;
                         userBufPtr += NumOuputChannels;
                 }
         }
 }
 
 //-------------------------------------------------------------------------------------------------------------------------------------------------------
-static void Output_Int8_Int32(ASIOBufferInfo* nativeBuffer, char *outBufPtr, int framePerBuffer, int NumInputChannels, int NumOuputChannels, int index, int hostFrameOffset,int userFrameOffset, bool swap)
+ void Output_Int8_Int32(ASIOBufferInfo* nativeBuffer, char *outBufPtr, int framePerBuffer, int NumInputChannels, int NumOuputChannels, int index, int hostFrameOffset,int userFrameOffset, bool swap)
 {
         long temp;
         int i,j;
@@ -1557,7 +1569,7 @@ static void Output_Int8_Int32(ASIOBufferInfo* nativeBuffer, char *outBufPtr, int
 
 //-------------------------------------------------------------------------------------------------------------------------------------------------------
 // MUST BE CHECKED
-static void Output_Int8_Float32(ASIOBufferInfo* nativeBuffer, char *outBufPtr, int framePerBuffer, int NumInputChannels, int NumOuputChannels, int index, int hostFrameOffset,int userFrameOffset, bool swap)
+ void Output_Int8_Float32(ASIOBufferInfo* nativeBuffer, char *outBufPtr, int framePerBuffer, int NumInputChannels, int NumOuputChannels, int index, int hostFrameOffset,int userFrameOffset, bool swap)
 {
         long temp;
         int i,j;
@@ -1576,7 +1588,7 @@ static void Output_Int8_Float32(ASIOBufferInfo* nativeBuffer, char *outBufPtr, i
 }
 
 //-------------------------------------------------------------------------------------------------------------------------------------------------------
-static void Output_IntU8_Int16(ASIOBufferInfo* nativeBuffer, unsigned char *outBufPtr, int framePerBuffer, int NumInputChannels, int NumOuputChannels, int index, int hostFrameOffset,int userFrameOffset, bool swap)
+ void Output_IntU8_Int16(ASIOBufferInfo* nativeBuffer, unsigned char *outBufPtr, int framePerBuffer, int NumInputChannels, int NumOuputChannels, int index, int hostFrameOffset,int userFrameOffset, bool swap)
 {
         long temp;
         int i,j;
@@ -1589,14 +1601,14 @@ static void Output_IntU8_Int16(ASIOBufferInfo* nativeBuffer, unsigned char *outB
                 {
                         temp = ((short)((*userBufPtr) - 0x80)) << 8;
                         if (swap) temp = SwapShort(temp);
-                        asioBufPtr[i] = (short)temp;
+                        asioBufPtr[i] = temp;
                         userBufPtr += NumOuputChannels;
                 }
         }
 }       
 
 //-------------------------------------------------------------------------------------------------------------------------------------------------------
-static void Output_IntU8_Int32(ASIOBufferInfo* nativeBuffer, unsigned char *outBufPtr, int framePerBuffer, int NumInputChannels, int NumOuputChannels, int index, int hostFrameOffset,int userFrameOffset, bool swap)
+ void Output_IntU8_Int32(ASIOBufferInfo* nativeBuffer, unsigned char *outBufPtr, int framePerBuffer, int NumInputChannels, int NumOuputChannels, int index, int hostFrameOffset,int userFrameOffset, bool swap)
 {
         long temp;
         int i,j;
@@ -1618,7 +1630,7 @@ static void Output_IntU8_Int32(ASIOBufferInfo* nativeBuffer, unsigned char *outB
 //-------------------------------------------------------------------------------------------------------------------------------------------------------
 // MUST BE CHECKED
 
-static void Output_IntU8_Float32(ASIOBufferInfo* nativeBuffer, unsigned char *outBufPtr, int framePerBuffer, int NumInputChannels, int NumOuputChannels, int index, int hostFrameOffset,int userFrameOffset, bool swap)
+ void Output_IntU8_Float32(ASIOBufferInfo* nativeBuffer, unsigned char *outBufPtr, int framePerBuffer, int NumInputChannels, int NumOuputChannels, int index, int hostFrameOffset,int userFrameOffset, bool swap)
 {
         long temp;
         int i,j;
@@ -1637,7 +1649,7 @@ static void Output_IntU8_Float32(ASIOBufferInfo* nativeBuffer, unsigned char *ou
 }
 
 //-------------------------------------------------------------------------------------------------------------------------------------------------------
-static void Pa_ASIO_Clear_Output_16 (ASIOBufferInfo* nativeBuffer, long frames, long NumInputChannels, long NumOuputChannels, long index, long hostFrameOffset)
+ void Pa_ASIO_Clear_Output_16 (ASIOBufferInfo* nativeBuffer, int frames, int NumInputChannels, int NumOuputChannels, int index, int hostFrameOffset)
 {
         int i,j;
 
@@ -1648,7 +1660,7 @@ static void Pa_ASIO_Clear_Output_16 (ASIOBufferInfo* nativeBuffer, long frames,
 }
 
 //-------------------------------------------------------------------------------------------------------------------------------------------------------
-static void Pa_ASIO_Clear_Output_32 (ASIOBufferInfo* nativeBuffer, long frames, long NumInputChannels, long NumOuputChannels, long index, long hostFrameOffset)
+ void Pa_ASIO_Clear_Output_32 (ASIOBufferInfo* nativeBuffer, int frames, int NumInputChannels, int NumOuputChannels, int index, int hostFrameOffset)
 {
         int i,j;
 
@@ -1660,7 +1672,7 @@ static void Pa_ASIO_Clear_Output_32 (ASIOBufferInfo* nativeBuffer, long frames,
 
 
 //-------------------------------------------------------------------------------------------------------------------------------------------------------
-static void Pa_ASIO_Adaptor_Init()
+void Pa_ASIO_Adaptor_Init()
 {
        if (asioDriverInfo.past->past_FramesPerUserBuffer <= asioDriverInfo.past_FramesPerHostBuffer) {
                asioDriverInfo.pahsc_hostOutputBufferFrameOffset = asioDriverInfo.pahsc_OutputBufferOffset;
@@ -1676,7 +1688,7 @@ static void Pa_ASIO_Adaptor_Init()
 
 //-------------------------------------------------------------------------------------------------------------------------------------------------------
 // FIXME : optimization for Input only or output only modes (really necessary ??)
-static void Pa_ASIO_Callback_Input( long index)
+void Pa_ASIO_Callback_Input( long index)
 {
         internalPortAudioStream  *past = asioDriverInfo.past;
         long framesInputHostBuffer = asioDriverInfo.past_FramesPerHostBuffer; // number of frames available into the host input buffer
@@ -1774,7 +1786,7 @@ static void Pa_ASIO_Callback_Input( long index)
 }
 
 //-------------------------------------------------------------------------------------------------------------------------------------------------------
-static void Pa_ASIO_Callback_Output(long index, long framePerBuffer)
+void Pa_ASIO_Callback_Output(long index, long framePerBuffer)
 {
         internalPortAudioStream *past = asioDriverInfo.past;
         
@@ -1801,14 +1813,14 @@ static void Pa_ASIO_Callback_Output(long index, long framePerBuffer)
         }
 }
 //-------------------------------------------------------------------------------------------------------------------------------------------------------
-static void Pa_ASIO_Callback_End()
+ void Pa_ASIO_Callback_End()
  {
         /* Empty ASIO ouput : write offset */
      asioDriverInfo.pahsc_hostOutputBufferFrameOffset = 0;
  }
 
 //-------------------------------------------------------------------------------------------------------------------------------------------------------
-static void Pa_ASIO_Clear_User_Buffers()
+void Pa_ASIO_Clear_User_Buffers()
 {
        if( asioDriverInfo.past->past_InputBuffer != NULL )
        {
@@ -1821,13 +1833,13 @@ static void Pa_ASIO_Clear_User_Buffers()
 }
 
 //-------------------------------------------------------------------------------------------------------------------------------------------------------
static void Pa_ASIO_Clear_Output(ASIOBufferInfo* nativeBuffer, 
+ void Pa_ASIO_Clear_Output(ASIOBufferInfo* nativeBuffer, 
         ASIOSampleType nativeFormat,
-        long NumInputChannels, 
-        long NumOuputChannels,
-        long index, 
-        long hostFrameOffset, 
-        long frames)
+        short NumInputChannels, 
+        short NumOuputChannels,
+        int index, 
+        int hostFrameOffset, 
+        int frames)
 {
         
         switch (nativeFormat) {
@@ -1867,18 +1879,18 @@ static void Pa_ASIO_Clear_User_Buffers()
 
 
 //---------------------------------------------------------------------------------------
-static void Pa_ASIO_Convert_Inter_Input(
+void Pa_ASIO_Convert_Inter_Input(
                 ASIOBufferInfo* nativeBuffer, 
                 void* inputBuffer,
-                       long NumInputChannels, 
-                       long NumOuputChannels,
-                       long framePerBuffer,
-                       long hostFrameOffset,
-                       long userFrameOffset,
+                       short NumInputChannels, 
+                       short NumOuputChannels,
+                       short framePerBuffer,
+                       short hostFrameOffset,
+                       short userFrameOffset,
                        ASIOSampleType nativeFormat, 
                        PaSampleFormat paFormat, 
                        PaStreamFlags flags,
-                       long index)
+                       short index)
 {
                 
         if((NumInputChannels > 0) && (nativeBuffer != NULL))
@@ -1892,22 +1904,22 @@ static void Pa_ASIO_Convert_Inter_Input(
                              
                                 switch (nativeFormat) {
                                         case ASIOSTInt16LSB:
-                                                Input_Int16_Float32(nativeBuffer, inBufPtr, framePerBuffer, NumInputChannels, index, hostFrameOffset, userFrameOffset, swap);
+                                                Input_Int16_Flot32(nativeBuffer, inBufPtr, framePerBuffer, NumInputChannels, index, hostFrameOffset, userFrameOffset, swap);
                                                 break;  
                                         case ASIOSTInt16MSB:
-                                                Input_Int16_Float32(nativeBuffer, inBufPtr, framePerBuffer, NumInputChannels, index, hostFrameOffset, userFrameOffset,!swap);
+                                                Input_Int16_Flot32(nativeBuffer, inBufPtr, framePerBuffer, NumInputChannels, index, hostFrameOffset, userFrameOffset,!swap);
                                                 break;  
                                         case ASIOSTInt32LSB:
-                                                Input_Int32_Float32(nativeBuffer, inBufPtr, framePerBuffer, NumInputChannels, index, hostFrameOffset, userFrameOffset,swap);
+                                                Input_Int32_Flot32(nativeBuffer, inBufPtr, framePerBuffer, NumInputChannels, index, hostFrameOffset, userFrameOffset,swap);
                                                 break;
                                         case ASIOSTInt32MSB:
-                                                Input_Int32_Float32(nativeBuffer, inBufPtr, framePerBuffer, NumInputChannels, index, hostFrameOffset, userFrameOffset,!swap);
+                                                Input_Int32_Flot32(nativeBuffer, inBufPtr, framePerBuffer, NumInputChannels, index, hostFrameOffset, userFrameOffset,!swap);
                                                 break;  
                                         case ASIOSTFloat32LSB:          // IEEE 754 32 bit float, as found on Intel x86 architecture
-                                                Input_Float32_Float32(nativeBuffer, inBufPtr, framePerBuffer, NumInputChannels, index, hostFrameOffset, userFrameOffset,swap);
+                                                Input_Float32_Flot32(nativeBuffer, inBufPtr, framePerBuffer, NumInputChannels, index, hostFrameOffset, userFrameOffset,swap);
                                                 break;  
                                         case ASIOSTFloat32MSB:          // IEEE 754 32 bit float, as found on Intel x86 architecture
-                                                Input_Float32_Float32(nativeBuffer, inBufPtr, framePerBuffer, NumInputChannels, index, hostFrameOffset, userFrameOffset,!swap);
+                                                Input_Float32_Flot32(nativeBuffer, inBufPtr, framePerBuffer, NumInputChannels, index, hostFrameOffset, userFrameOffset,!swap);
                                                 break;  
                                         
                                         case ASIOSTInt24LSB:            // used for 20 bits as well
@@ -2147,20 +2159,20 @@ static void Pa_ASIO_Convert_Inter_Input(
 
 
 //---------------------------------------------------------------------------------------
-static void Pa_ASIO_Convert_Inter_Output(ASIOBufferInfo* nativeBuffer, 
+void Pa_ASIO_Convert_Inter_Output(ASIOBufferInfo* nativeBuffer, 
                 void* outputBuffer,
-                               long NumInputChannels, 
-                               long NumOuputChannels,
-                       long framePerBuffer,
-                       long hostFrameOffset,
-                       long userFrameOffset,
+                               short NumInputChannels, 
+                               short NumOuputChannels,
+                       short framePerBuffer,
+                       short hostFrameOffset,
+                       short userFrameOffset,
                        ASIOSampleType nativeFormat, 
                        PaSampleFormat paFormat, 
                        PaStreamFlags flags,
-                       long index)
+                       short index)
 {
    
-        if((NumOuputChannels > 0) && (nativeBuffer != NULL)) 
+           if((NumOuputChannels > 0) && (nativeBuffer != NULL)) 
         {
                 /* Convert from PA format to native format */
                 
@@ -2427,7 +2439,7 @@ static PaError Pa_ASIO_loadDevice (long device)
 {
         PaDeviceInfo * dev = &(sDevices[device].pad_Info);
 
-        if (!Pa_ASIO_loadAsioDriver((char *) dev->name)) return paHostError;
+        if (!loadAsioDriver((char *) dev->name)) return paHostError;
         if (ASIOInit(&asioDriverInfo.pahsc_driverInfo) != ASE_OK) return paHostError;
         if (ASIOGetChannels(&asioDriverInfo.pahsc_NumInputChannels, &asioDriverInfo.pahsc_NumOutputChannels) != ASE_OK) return paHostError;
         if (ASIOGetBufferSize(&asioDriverInfo.pahsc_minSize, &asioDriverInfo.pahsc_maxSize, &asioDriverInfo.pahsc_preferredSize, &asioDriverInfo.pahsc_granularity) != ASE_OK) return paHostError;
@@ -2441,7 +2453,7 @@ static PaError Pa_ASIO_loadDevice (long device)
 }
 
 //---------------------------------------------------
-static int GetHighestBitPosition (unsigned long n)
+static int GetHighestBitPosition( unsigned long n )
 {
         int pos = -1;
         while( n != 0 )
@@ -2452,10 +2464,10 @@ static int GetHighestBitPosition (unsigned long n)
         return pos;
 }
 
-//------------------------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
 static int GetFirstMultiple(long min, long val ){  return ((min + val - 1) / val) * val; }
 
-//------------------------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
 static int GetFirstPossibleDivisor(long max, long val )
 { 
        for (int i = 2; i < 20; i++) {if (((val%i) == 0) && ((val/i) <= max)) return (val/i); }
@@ -2567,9 +2579,8 @@ error:
 /***********************************************************************/
 PaError PaHost_Init( void )
 {
-       /* Have we already initialized the device info? */
-        PaError err = (PaError) Pa_CountDevices();
-       return ( err < 0 ) ? err : paNoError;
+        /* Have we already initialized the device info? */
+        return  (Pa_CountDevices() < 0 ) ? paHostError : paNoError;
 }
 
 /***********************************************************************/
@@ -2578,30 +2589,26 @@ PaError PaHost_Term( void )
         int           i;
         PaDeviceInfo *dev;
         double       *rates;
-        PaError      result = paNoError;
-         
-        if (sNumDevices > 0) {
-               
-               /* Free allocated sample rate arrays  and names*/
-               for( i=0; i<sNumDevices; i++ ){
-                       dev =  &sDevices[i].pad_Info;
-                       rates = (double *) dev->sampleRates;
-                       if ((rates != NULL)) PaHost_FreeFastMemory(rates, MAX_NUMSAMPLINGRATES * sizeof(double)); 
-                       dev->sampleRates = NULL;
-                      if(dev->name != NULL) PaHost_FreeFastMemory((void *) dev->name, 32);
-                       dev->name = NULL;
-                       
-               }
-               
-               sNumDevices = 0;
-               
-                /* Dispose : if not done by Pa_CloseStream     */
-               if(ASIODisposeBuffers() != ASE_OK) result = paHostError;        
-               if(ASIOExit() != ASE_OK) result = paHostError;
-               
-               /* remove the loaded ASIO driver */
-               asioDrivers->removeCurrentDriver();
-           }
+         PaError      result = paNoError;
+        
+        /* Free allocated sample rate arrays  and names*/
+        for( i=0; i<sNumDevices; i++ ){
+                dev =  &sDevices[i].pad_Info;
+                rates = (double *) dev->sampleRates;
+                if((rates != NULL)) PaHost_FreeFastMemory(rates, MAX_NUMSAMPLINGRATES * sizeof(double)); 
+                dev->sampleRates = NULL;
+                if(dev->name != NULL) PaHost_FreeFastMemory((void *) dev->name, 32);
+                dev->name = NULL;
+        }
+        
+        sNumDevices = 0;
+        
+         /* Dispose : if not done by Pa_CloseStream    */
+        if(ASIODisposeBuffers() != ASE_OK) result = paHostError;        
+        if(ASIOExit() != ASE_OK) result = paHostError;
+        
+        /* remove the loaded ASIO driver */
+        asioDrivers->removeCurrentDriver();
 
         return result;
 }
@@ -2613,8 +2620,8 @@ PaError PaHost_OpenStream( internalPortAudioStream   *past )
         ASIOError                       err;
         int32                           device;
         
-        /*  Check if a stream already runs */
-        if (asioDriverInfo.past != NULL) return paHostError;
+        /*  TO DO : Check if a stream already runs */
+        //if (asioDriverInfo.past != NULL) return paHostError; (does not work)
                         
         /* Check the device number */
         if ((past->past_InputDeviceID != paNoDevice)
diff --git a/pa_asio/readme_asio_sdk_patch.txt b/pa_asio/readme_asio_sdk_patch.txt
deleted file mode 100755 (executable)
index c0fdca7..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-There is a bug in the ASIO SDK that causes the Macintosh version to often fail during initialization. Here is a patch that you can apply.
-
-In codefragments.cpp replace getFrontProcessDirectory function with 
-the following one (GetFrontProcess replaced by GetCurrentProcess)
-
-
-bool CodeFragments::getFrontProcessDirectory(void *specs)
-{
-       FSSpec *fss = (FSSpec *)specs;
-       ProcessInfoRec pif;
-       ProcessSerialNumber psn;
-
-       memset(&psn,0,(long)sizeof(ProcessSerialNumber));
-       //  if(GetFrontProcess(&psn) == noErr)  // wrong !!!
-       if(GetCurrentProcess(&psn) == noErr)  // correct !!!
-       {
-               pif.processName = 0;
-               pif.processAppSpec = fss;
-               pif.processInfoLength = sizeof(ProcessInfoRec);
-               if(GetProcessInformation(&psn, &pif) == noErr)
-                               return true;
-       }
-       return false;
-}
-
diff --git a/pa_common/pa_convert.c b/pa_common/pa_convert.c
deleted file mode 100644 (file)
index 377a955..0000000
+++ /dev/null
@@ -1,402 +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++ )
-       {
-        long 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;
-        long 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++ )
-       {
-        long samp = *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;
-        long 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;
-        long 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 = 128 + (unsigned char) (*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 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 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;
-        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.
-*/
-long 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;
-}
index 94651a22626a49cc9fb40480e01b7f5c2940326c..9a3526129736de3d86792dfbf2a21f9fba690591 100644 (file)
@@ -36,8 +36,6 @@
  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  *
  */
-#include "portaudio.h"
 
 #ifdef __cplusplus
 extern "C"
@@ -61,12 +59,6 @@ extern "C"
     typedef unsigned short 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)
 
 /************************************************************************************/
@@ -84,9 +76,7 @@ typedef struct internalPortAudioStream
     int                       past_NumOutputChannels;
     PaDeviceID                past_InputDeviceID;
     PaDeviceID                past_OutputDeviceID;
-    PaSampleFormat            past_NativeInputSampleFormat;
     PaSampleFormat            past_InputSampleFormat;
-    PaSampleFormat            past_NativeOutputSampleFormat;
     PaSampleFormat            past_OutputSampleFormat;
     void                     *past_DeviceData;
     PortAudioCallback        *past_Callback;
@@ -109,19 +99,11 @@ typedef struct internalPortAudioStream
     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. ************/
+/****************** Prototypes ******************************************************/
 /************************************************************************************/
 
 PaError PaHost_Init( void );
@@ -138,47 +120,22 @@ PaError PaHost_StartEngine( internalPortAudioStream   *past );
 PaError PaHost_StopEngine( internalPortAudioStream *past, int abort );
 PaError PaHost_StreamActive( internalPortAudioStream   *past );
 
+long Pa_CallConvertInt16( internalPortAudioStream   *past,
+                          short *nativeInputBuffer,
+                          short *nativeOutputBuffer );
+
+long Pa_CallConvertFloat32( internalPortAudioStream   *past,
+                            float *nativeInputBuffer,
+                            float *nativeOutputBuffer );
+
 void   *PaHost_AllocateFastMemory( long numBytes );
 void    PaHost_FreeFastMemory( void *addr, long 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 );
 
-long 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))
-long PaConvert_TriangularDither( void );
-
-PaError PaConvert_SetupInput( internalPortAudioStream   *past,
-    PaSampleFormat   nativeInputSampleFormat );
-
-PaError PaConvert_SetupOutput( internalPortAudioStream   *past,
-    PaSampleFormat   nativeOutputSampleFormat );
-
-long PaConvert_Process( internalPortAudioStream   *past,
-            void *nativeInputBuffer,
-            void *nativeOutputBuffer );
-
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
index 3df5ec59c8495b57339e87dd26beb14fe8890d9f..f32c635227e59047658b587fb988553f0deff9b7 100644 (file)
@@ -70,8 +70,8 @@ O- maybe not allocate past_InputBuffer and past_OutputBuffer if not needed for c
 
 #define PRINT(x) { printf x; fflush(stdout); }
 #define ERR_RPT(x) PRINT(x)
-#define DBUG(x)  /* PRINT(x) /**/
-#define DBUGX(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. */
 
@@ -152,10 +152,10 @@ PaError Pa_OpenStream(
     int                        bitsPerInputSample;
     int                        bitsPerOutputSample;
     /* Print passed parameters. */
-    DBUG(("Pa_OpenStream( %p, dev=%d, numChan=%d, format=%d, info=%p, /* input */ \n",
+    DBUG(("Pa_OpenStream( %p, %d, %d, %d, %p, /* input */ \n",
           streamPtrPtr, inputDeviceID, numInputChannels,
           inputSampleFormat, inputDriverInfo ));
-    DBUG(("               dev=%d, numChan=%d, format=%d, info=%p, /* output */\n",
+    DBUG(("               %d, %d, %d, %p, /* output */\n",
           outputDeviceID, numOutputChannels,
           outputSampleFormat, outputDriverInfo ));
     DBUG(("               %g, %d, %d, 0x%x, , %p )\n",
@@ -217,7 +217,7 @@ PaError Pa_OpenStream(
 
     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_NumUserBuffers = numberOfBuffers; /* NOTE - PaHost_OpenStream() NMUST CHECK FOR ZERO! */
     past->past_Callback = callback;
     past->past_UserData = userData;
     past->past_OutputSampleFormat = outputSampleFormat;
@@ -248,7 +248,7 @@ PaError Pa_OpenStream(
 #else
         past->past_SampleRate = sampleRate;
 #endif
-        /* Allocate single Input buffer for passing formatted samples to user callback. */
+        /* Allocate single Input buffer. */
         past->past_InputBufferSize = framesPerBuffer * numInputChannels * ((bitsPerInputSample+7) / 8);
         past->past_InputBuffer = PaHost_AllocateFastMemory(past->past_InputBufferSize);
         if( past->past_InputBuffer == NULL )
@@ -478,25 +478,13 @@ double Pa_GetCPULoad(  PortAudioStream* 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))
-long PaConvert_TriangularDither( void )
+#define DITHER_BITS   (15)
+#define DITHER_SCALE  (1.0f / ((1<<DITHER_BITS)-1))
+static long Pa_TriangularDither( void )
 {
     static unsigned long previous = 0;
     static unsigned long randSeed1 = 22222;
@@ -505,12 +493,8 @@ long PaConvert_TriangularDither( void )
     /* 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);
+    /* Generate triangular distribution about 0. */
+    current = (((long)randSeed1)>>(32-DITHER_BITS)) + (((long)randSeed2)>>(32-DITHER_BITS));
     /* High pass filter to reduce audibility. */
     highPass = current - previous;
     previous = current;
@@ -529,6 +513,8 @@ long Pa_CallConvertInt16( internalPortAudioStream   *past,
                           short *nativeOutputBuffer )
 {
     long              temp;
+    long              bytesEmpty = 0;
+    long              bytesFilled = 0;
     int               userResult;
     unsigned int      i;
     void             *inputBuffer = NULL;
@@ -590,7 +576,7 @@ long Pa_CallConvertInt16( internalPortAudioStream   *past,
                     for( i=0; i<samplesPerBuffer; i++ )
                     {
                         temp = nativeInputBuffer[i];
-                        temp += PaConvert_TriangularDither() >> 8; /* PLB20010820 */
+                        temp += Pa_TriangularDither() >> 8; /* PLB20010820 */
                         temp = ((temp < -0x8000) ? -0x8000 : ((temp > 0x7FFF) ? 0x7FFF : temp));
                         inBufPtr[i] = (char)(temp >> 8);
                     }
@@ -616,7 +602,7 @@ long Pa_CallConvertInt16( internalPortAudioStream   *past,
                     for( i=0; i<samplesPerBuffer; i++ )
                     {
                         temp = nativeInputBuffer[i];
-                        temp += PaConvert_TriangularDither() >> 8; /* PLB20010820 */
+                        temp += Pa_TriangularDither() >> 8; /* PLB20010820 */
                         temp = ((temp < -0x8000) ? -0x8000 : ((temp > 0x7FFF) ? 0x7FFF : temp));
                         inBufPtr[i] = (unsigned char)((temp>>8) + 0x80); /* PLB20010820 */
                     }
@@ -683,7 +669,7 @@ long Pa_CallConvertInt16( internalPortAudioStream   *past,
                     /* 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 dither  = Pa_TriangularDither()*DITHER_SCALE;
                         float dithered = (outBufPtr[i] * (32767.0f)) + dither;
                         temp = (long) (dithered);
                         *nativeOutputBuffer++ = (short)((temp < -0x8000) ? -0x8000 : ((temp > 0x7FFF) ? 0x7FFF : temp));
@@ -707,7 +693,7 @@ long Pa_CallConvertInt16( internalPortAudioStream   *past,
                     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 = (outBufPtr[i] >> 1) + Pa_TriangularDither();
                         temp = temp >> 15;
                         *nativeOutputBuffer++ = (short)((temp < -0x8000) ? -0x8000 : ((temp > 0x7FFF) ? 0x7FFF : temp));
                     }
@@ -744,6 +730,55 @@ long Pa_CallConvertInt16( internalPortAudioStream   *past,
     return userResult;
 }
 
+/*************************************************************************
+** Called by host code.
+** Convert input from Float32, call user code, then convert output
+** to Float32 format for native use.
+** Assumes host native format is Float32.
+** Returns result from user callback.
+** FIXME - Unimplemented for formats other than paFloat32!!!!
+*/
+long Pa_CallConvertFloat32( internalPortAudioStream   *past,
+                            float *nativeInputBuffer,
+                            float *nativeOutputBuffer )
+{
+    long              bytesEmpty = 0;
+    long              bytesFilled = 0;
+    int               userResult;
+    void             *inputBuffer = NULL;
+    void             *outputBuffer = NULL;
+
+    /* Get native data from DirectSound. */
+    if( (past->past_NumInputChannels > 0) && (nativeInputBuffer != NULL) )
+    {
+        inputBuffer = nativeInputBuffer;  /* FIXME */
+    }
+
+    /* 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 == paFloat32) ?
+                       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. */  /* FIXME */
+    return userResult;
+}
+
 /*************************************************************************/
 PaError Pa_Initialize( void )
 {
@@ -765,11 +800,6 @@ PaError Pa_Terminate( void )
     return result;
 }
 
-int PaHost_IsInitialized()
-{
-    return gInitCount;
-}
-
 /*************************************************************************/
 PaError Pa_GetSampleSize( PaSampleFormat format )
 {
index fe05829037cc7dc605b12c539c05d36b176c7b74..231e804ec342effe75c88f422c0c44ef24d73b10 100644 (file)
@@ -63,7 +63,6 @@ typedef enum {
 /*
  Pa_Initialize() is the library initialisation function - call this before
  using the library.
-
 */
 
 PaError Pa_Initialize( void );
@@ -71,25 +70,19 @@ 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.
-
+ Return host specific error.
+ This can be called after receiving a paHostError.
 */
-
 long Pa_GetHostError( void );
 
 /*
- Pa_GetErrorText() translates the supplied PortAudio error number
- into a human readable message.
+ Translate the error number into a human readable message.
 */
-
 const char *Pa_GetErrorText( PaError errnum );
 
 /*
@@ -99,14 +92,11 @@ const char *Pa_GetErrorText( PaError errnum );
  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.
+ Formats marked "always available" are supported (emulated) by all devices.
+ The floating point representation uses +1.0 and -1.0 as the respective
+ maximum and minimum.
  
- 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 unsigned long PaSampleFormat;
@@ -116,23 +106,24 @@ typedef unsigned long PaSampleFormat;
 #define paInt24        ((PaSampleFormat) (1<<3))
 #define paPackedInt24  ((PaSampleFormat) (1<<4))
 #define paInt8         ((PaSampleFormat) (1<<5))
-#define paUInt8        ((PaSampleFormat) (1<<6))
+#define paUInt8        ((PaSampleFormat) (1<<6))    /* unsigned 8 bit, 128 is "ground" */
 #define paCustomFormat ((PaSampleFormat) (1<<16))
 
 /*
  Device enumeration mechanism.
  
- Device ids range from 0 to Pa_CountDevices()-1.
   Device ids range from 0 to Pa_CountDevices()-1.
  
- Devices may support input, output or both.
-
+ Devices may support input, output or both. Device 0 is always the "default"
+ device and should support at least stereo in and out if that is available
+ on the taget platform _even_ if this involves kludging an input/output
+ device on platforms that usually separate input from output. Other platform
+ specific devices are specified by positive device ids.
 */
 
 typedef int PaDeviceID;
 #define paNoDevice -1
 
-int Pa_CountDevices( void );
-
 typedef struct
 {
     int structVersion;
@@ -147,10 +138,12 @@ typedef struct
 }
 PaDeviceInfo;
 
+
+int Pa_CountDevices();
 /*
- Pa_GetDefaultInputDeviceID(), Pa_GetDefaultOutputDeviceID() return the
- default device ids for input and output respectively, or paNoDevice if
no device is available.
+ Pa_GetDefaultInputDeviceID(), Pa_GetDefaultOutputDeviceID()
Return the default device ID or paNoDevice if there is no devices.
  The result can be passed to Pa_OpenStream().
  
  On the PC, the user can specify a default device by
@@ -158,40 +151,34 @@ PaDeviceInfo;
  
   set PA_RECOMMENDED_OUTPUT_DEVICE=1
  
- The user should first determine the available device ids by using
+ The user should first determine the available device ID 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().
-
+ PaTimestamp is used to represent a continuous sample clock with arbitrary
+ start time useful for syncronisation. The type is used in the outTime
+ argument to the callback function and the result of Pa_StreamTime()
 */
 
-const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceID device );
+typedef double PaTimestamp;
 
 /*
- 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()
-
+ Pa_GetDeviceInfo() returns a pointer to an immutable PaDeviceInfo structure
+ referring to the device specified by id.
+ If id is out of range the function returns NULL.
+ The returned structure is owned by the PortAudio implementation and must
+ not be manipulated or freed. The pointer is only guaranteed to be valid
+ between calls to Pa_Initialize() and Pa_Terminate().
 */
 
-typedef double PaTimestamp;
+const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceID devID );
 
 /*
- PortAudioCallback is implemented by PortAudio clients.
+ PortAudioCallback is implemented by clients of the portable audio api.
  
  inputBuffer and outputBuffer are arrays of interleaved samples,
  the format, packing and number of channels used by the buffers are
@@ -207,15 +194,15 @@ typedef double PaTimestamp;
  intended for storing synthesis data etc.
  
  return value:
- The callback can return a non-zero value to stop the stream. This may be
+ The callback can return a nonzero 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.
+ nonzero 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)(
@@ -229,11 +216,12 @@ typedef int (PortAudioCallback)(
  
  These flags may be supplied (ored together) in the streamFlags argument to
  the Pa_OpenStream() function.
-
+ [ suggestions? ]
 */
 
 #define   paNoFlag      (0)
-#define   paClipOff     (1<<0)   /* disable default clipping of out of range samples */
+#define   paClipOff     (1<<0)   /* disable defult clipping of out of range samples */
 #define   paDitherOff   (1<<1)   /* disable default dithering */
 #define   paPlatformSpecificFlags (0x00010000)
 typedef   unsigned long PaStreamFlags;
@@ -258,15 +246,15 @@ typedef void PortAudioStream;
  
  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.
device input record for the device specified in the inputDevice parameter.
  If inputDevice is paNoDevice numInputChannels is ignored.
  
- inputSampleFormat is the sample format of inputBuffer provided to the callback
+ inputSampleFormat is the 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.
+ the sound devices 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.
@@ -288,24 +276,24 @@ typedef void PortAudioStream;
  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
+ sampleRate is the desired sampleRate for 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.)
+ 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.
+ These flags modify the behavior 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.)
@@ -315,10 +303,10 @@ typedef void PortAudioStream;
  for processing the audio buffers.
  
  return value:
Upon success Pa_OpenStream() returns PaNoError and places a pointer to a
Apon 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.
+ If a call to Pa_OpenStream() fails a nonzero error code is returned (see
+ PAError above) and the value of stream is invalid.
  
 */
 
@@ -340,16 +328,15 @@ PaError Pa_OpenStream( PortAudioStream** stream,
 
 
 /*
- 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:
+ Pa_OpenDefaultStream() is a simplified version of Pa_OpenStream() that
+ opens the default input and/or ouput 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().
+ is not opened (same as passing paNoDevice in the device arguments to Pa_OpenStream() )
  
  sampleFormat applies to both the input and output buffers.
-
 */
 
 PaError Pa_OpenDefaultStream( PortAudioStream** stream,
@@ -364,17 +351,15 @@ PaError Pa_OpenDefaultStream( PortAudioStream** stream,
 
 /*
  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_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.
-    
+    Pa_AbortStream() stops playing immediately without waiting for pending
+    buffers to complete.
 */
 
 PaError Pa_StartStream( PortAudioStream *stream );
@@ -384,43 +369,37 @@ 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.
+ Pa_StreamActive() returns one when the stream is playing audio,
+ zero 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
+ Pa_StreamTime() returns the current output time for the stream in samples.
+ This time may be used as a time reference (for example syncronising 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.
+ The "CPU Load" is a fraction of total CPU time consumed by the
+ stream's audio processing.
  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.
+ Use Pa_GetMinNumBuffers() to determine minimum number of buffers required for
+ 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:
@@ -430,33 +409,23 @@ double Pa_GetCPULoad( PortAudioStream* stream );
  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.)
+ Sleep for at least 'msec' milliseconds.
+ You may sleep longer than the requested time so don't rely
+ on this for accurate musical timing.
 */
-
 void Pa_Sleep( long msec );
 
 /*
- Pa_GetSampleSize() returns the size in bytes of a single sample in the
- supplied PaSampleFormat, or paSampleFormatNotSupported if the format is
- no supported.
-  
+ Return size in bytes of a single sample in a given PaSampleFormat
+ or paSampleFormatNotSupported. 
 */
-
 PaError Pa_GetSampleSize( PaSampleFormat format );
 
-
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
index 7a8e03009d25cf823c729c795708a21f3be9090b..cde9a95fe7136578055a728d8e153b1fe9df4a70 100644 (file)
    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 form hanging when CPU load approaches 100%.
-   PLB20020424 - Fixed return value in Pa_StreamTime
 */
-
 /*
 COMPATIBILITY
 This Macintosh implementation is designed for use with Mac OS 7, 8 and
@@ -81,7 +72,6 @@ O- Determine default devices somehow.
 #include <string.h>
 #include <memory.h>
 #include <math.h>
-
 /* Mac specific includes */
 #include "OSUtils.h"
 #include <MacTypes.h>
@@ -94,7 +84,6 @@ O- Determine default devices somehow.
 #include <DateTimeUtils.h>
 #include <Timer.h>
 #include <Gestalt.h>
-
 #include "portaudio.h"
 #include "pa_host.h"
 #include "pa_trace.h"
@@ -104,16 +93,6 @@ O- Determine default devices somehow.
  #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)
@@ -122,7 +101,7 @@ O- Determine default devices somehow.
 
 #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_MIN_NUM_HOST_BUFFERS           (2)
 #define PA_MAX_NUM_HOST_BUFFERS           (16)   /* Do not exceed!! */
 #define PA_MAX_DEVICE_INFO                (32)
 
@@ -147,8 +126,7 @@ MultiBuffer;
 typedef struct PaHostSoundControl
 {
     UInt64                  pahsc_EntryCount;
-       double                  pahsc_InverseMicrosPerHostBuffer; /* 1/Microseconds of real-time audio per user buffer. */
-
+    UInt64                  pahsc_LastExitCount;
     /* 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. */
@@ -156,23 +134,22 @@ typedef struct PaHostSoundControl
     /* Input */
     SPB                     pahsc_InputParams;
     SICompletionUPP         pahsc_InputCompletionProc;
-    MultiBuffer             pahsc_InputMultiBuffer;
-    int32                   pahsc_BytesPerInputHostBuffer;
+    MultiBuffer    pahsc_InputMultiBuffer;
+    int32     pahsc_BytesPerInputHostBuffer;
     int32                   pahsc_InputRefNum;
     /* Output */
     CmpSoundHeader          pahsc_SoundHeaders[PA_MAX_NUM_HOST_BUFFERS];
     int32                   pahsc_BytesPerOutputHostBuffer;
-    SndChannelPtr           pahsc_Channel;
+    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. */
+    int32     pahsc_MinFramesPerHostBuffer; /* Can vary depending on virtual memory usage. */
 }
 PaHostSoundControl;
 
@@ -200,8 +177,7 @@ static int                 sDefaultInputDeviceID;
 /************************************************************************************/
 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 PaError PaMac_RecordNext( internalPortAudioStream   *past );static void    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 );
@@ -720,8 +696,8 @@ PaDeviceID Pa_GetDefaultOutputDeviceID( void )
     return sDefaultOutputDeviceID;
 }
 
-/********************************* BEGIN CPU UTILIZATION MEASUREMENT ****/
-static void PaMac_StartLoadCalculation( internalPortAudioStream   *past )
+/**************************************************************************/
+static void StartLoadCalculation( internalPortAudioStream   *past )
 {
     PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;
     UnsignedWide widePad;
@@ -731,36 +707,38 @@ static void PaMac_StartLoadCalculation( internalPortAudioStream   *past )
     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;
-    long      usecsElapsed;
-    double    newUsage;
+    UInt64    CurrentCount;
+    long      InsideCount;
+    long      TotalCount;
     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_0   (0.9)
 #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);
+    CurrentCount = UnsignedWideToUInt64( widePad );
+    if( past->past_IfLastExitValid )
+    {
+        InsideCount = (long) U64Subtract(CurrentCount, pahsc->pahsc_EntryCount);
+        TotalCount  = (long) U64Subtract(CurrentCount, pahsc->pahsc_LastExitCount);
+        /* Low pass filter the result because sometimes we get called several times in a row.
+        * That can cause the TotalCount to be very low which can cause the usage to appear
+        * unnaturally high. So we must filter numerator and denominator separately!!!
+        */
+        past->past_AverageInsideCount = (( LOWPASS_COEFFICIENT_0 * past->past_AverageInsideCount) +
+                                         (LOWPASS_COEFFICIENT_1 * InsideCount));
+        past->past_AverageTotalCount = (( LOWPASS_COEFFICIENT_0 * past->past_AverageTotalCount) +
+                                        (LOWPASS_COEFFICIENT_1 * TotalCount));
+        past->past_Usage = past->past_AverageInsideCount / past->past_AverageTotalCount;
+    }
+    pahsc->pahsc_LastExitCount = CurrentCount;
+    past->past_IfLastExitValid = 1;
 }
 
 /***********************************************************************
@@ -851,14 +829,6 @@ static void PaMac_InitSoundHeader( internalPortAudioStream   *past, CmpSoundHead
     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 )
 {
@@ -874,8 +844,7 @@ PaError PaHost_StartOutput( internalPortAudioStream   *past )
     past->past_IsActive = 1;
     pahsc->pahsc_NumOutsQueued = 0;
     pahsc->pahsc_NumOutsPlayed = 0;
-    
-    SetFramesDone( pahsc, 0.0 );
+    pahsc->pahsc_NumFramesDone = 0.0;
 
     /* Pause channel so it does not do back ground processing while we are still filling the queue. */
     pauseCommand.cmd = pauseCmd;
@@ -888,7 +857,7 @@ PaError PaHost_StartOutput( internalPortAudioStream   *past )
     {
         PaMac_PlayNext( past, i );
     }
-    
+
     /* Resume channel now that the queue is full. */
     resumeCommand.cmd = resumeCmd;
     resumeCommand.param1 = resumeCommand.param2 = 0;
@@ -973,8 +942,8 @@ int Mac_IsVirtualMemoryOn( void )
 }
 
 /*******************************************************************
-* Determine number of host Buffers
-* and how many User Buffers we can put into each host buffer.
+* Determine number of WAVE Buffers
+* and how many User Buffers we can put into each WAVE buffer.
 */
 static void PaHost_CalcNumHostBuffers( internalPortAudioStream *past )
 {
@@ -985,23 +954,16 @@ static void PaHost_CalcNumHostBuffers( internalPortAudioStream *past )
     int32  userBuffersPerHostBuffer;
     int32  framesPerHostBuffer;
     int32  numHostBuffers;
-    
+    /* Calculate minimum and maximum sizes based on timing and sample rate. */
     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 );
-    
+    minNumBuffers = Pa_GetMinNumBuffers( 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. */
+    /* We cannot make the WAVE buffers too small because they may not get serviced quickly enough. */
     if( (int32) past->past_FramesPerUserBuffer < minFramesPerHostBuffer )
     {
         userBuffersPerHostBuffer =
@@ -1013,17 +975,16 @@ static void PaHost_CalcNumHostBuffers( internalPortAudioStream *past )
         userBuffersPerHostBuffer = 1;
     }
     framesPerHostBuffer = past->past_FramesPerUserBuffer * userBuffersPerHostBuffer;
-    
-    /* Calculate number of host buffers needed. Round up to cover minTotalFrames. */
+    /* Calculate number of WAVE buffers needed. Round up to cover minTotalFrames. */
     numHostBuffers = (minTotalFrames + framesPerHostBuffer - 1) / framesPerHostBuffer;
-    /* Make sure we have enough host buffers. */
+    /* Make sure we have anough WAVE 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. */
+        /* If we have too many WAVE buffers, try to put more user buffers in a wave buffer. */
         while(numHostBuffers > PA_MAX_NUM_HOST_BUFFERS)
         {
             userBuffersPerHostBuffer += 1;
@@ -1067,9 +1028,6 @@ PaError PaHost_OpenStream( internalPortAudioStream   *past )
     }
 
     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 )
@@ -1261,9 +1219,6 @@ PaError PaHost_CloseStream( internalPortAudioStream   *past )
 /*************************************************************************/
 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 );
 }
 /*************************************************************************/
@@ -1343,37 +1298,11 @@ void PaHost_FreeFastMemory( void *addr, long numBytes )
 /*************************************************************************/
 PaTimestamp Pa_StreamTime( PortAudioStream *stream )
 {
-       PaTimestamp   framesDone1;
-       PaTimestamp   framesDone2;
-       UInt64        whenIncremented;
-       UnsignedWide  now;
-       UInt64        now64;
-       long          microsElapsed;
-       long          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;
+    return pahsc->pahsc_NumFramesDone;
 }
 
 /**************************************************************************
@@ -1411,8 +1340,7 @@ pascal void PaMac_InputCompletionProc(SPBPtr recParams)
      */
     if(past->past_NumOutputChannels == 0)
     {
-               SetFramesDone( pahsc,
-                       pahsc->pahsc_NumFramesDone + pahsc->pahsc_FramesPerHostBuffer );
+        pahsc->pahsc_NumFramesDone += pahsc->pahsc_FramesPerHostBuffer; // Advance for recording
         result = PaMac_CallUserLoop( past, NULL );
     }
 
@@ -1443,7 +1371,6 @@ static PaError PaMac_CallUserLoop( internalPortAudioStream   *past, int16 *outPt
     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)
@@ -1458,33 +1385,22 @@ static PaError PaMac_CallUserLoop( internalPortAudioStream   *past, int16 *outPt
     /* 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;
-               }
-           }
-               
+        StartLoadCalculation( past ); /* CPU usage */
+
+        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;
@@ -1571,10 +1487,8 @@ static pascal void PaMac_OutputCompletionProc (SndChannelPtr theChannel, SndComm
 
     pahsc = (PaHostSoundControl *) past->past_DeviceData;
     pahsc->pahsc_NumOutsPlayed += 1;
+    pahsc->pahsc_NumFramesDone += pahsc->pahsc_FramesPerHostBuffer;
 
-       SetFramesDone( pahsc,
-                       pahsc->pahsc_NumFramesDone + pahsc->pahsc_FramesPerHostBuffer );
-                       
     PaMac_BackgroundManager( past, theCallBackCmd->param1 );
 }
 
@@ -1626,19 +1540,16 @@ static void PaMac_PlayNext ( internalPortAudioStream *past, int index )
 
     /* 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;
diff --git a/pa_mac_core/notes.txt b/pa_mac_core/notes.txt
deleted file mode 100644 (file)
index c79b90e..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-Notes on Core Audio Implementation of PortAudio
-
-by Phil Burk and Darren Gibbs
-
-Document last updated March 20, 2002
-
-WHAT WORKS
-
-Output with very low latency, <10 msec.
-Half duplex input or output.
-Full duplex on the same CoreAudio device.
-The paFLoat32, paInt16, paInt8, paUInt8 sample formats.
-Pa_GetCPULoad()
-Pa_StreamTime()
-
-KNOWN BUGS OR LIMITATIONS
-
-We do not yet support simultaneous input and output on different 
-devices. Note that some CoreAudio devices like the Roland UH30 look 
-like one device but are actually two different CoreAudio devices. The 
-BuiltIn audio is typically one CoreAudio device.
-
-Mono doesn't work.
-
-DEVICE MAPPING
-
-CoreAudio devices can support both input and output. But the sample 
-rates supported may be different. So we have map one or two PortAudio 
-device to each CoreAudio device depending on whether it supports 
-input, output or both.
-
-When we query devices, we first get a list of CoreAudio devices. Then 
-we scan the list and add a PortAudio device for each CoreAudio device 
-that supports input. Then we make a scan for output devices.
index e608402d4bfc038c9d02d8105ddf17815902f6db..3dc4d747a4dba2e2933d1fad6156a07df9b0630c 100644 (file)
  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.
-            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_LATEWNCY_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.
-
-TODO:
-O- how do mono output?
-O- FIFO between input and output callbacks if different devices, like in pa_mac.c
-*/
-
+ */
 #include <CoreServices/CoreServices.h>
 #include <CoreAudio/CoreAudio.h>
 #include <sys/time.h>
-#include <sys/resource.h>
 #include <unistd.h>
-
 #include "portaudio.h"
 #include "pa_host.h"
 #include "pa_trace.h"
 
 /************************************************* Constants ********/
+#define PA_USE_TIMER_CALLBACK    (0)  /* Select between two options for background task. 0=thread, 1=timer */
+#define PA_USE_HIGH_LATENCY      (0)  /* For debugging glitches. */
+
+/* Switches for debugging. */
+#define PA_SIMULATE_UNDERFLOW    (0)  /* Set to one to force an underflow of the output buffer. */
 
 /* To trace program, enable TRACE_REALTIME_EVENTS in pa_trace.h */
 #define PA_TRACE_RUN             (0)
 #define PA_TRACE_START_STOP      (1)
 
-#define PA_MIN_LATENCY_MSEC      (8)
-#define MIN_TIMEOUT_MSEC         (1000)
+#define PA_MIN_MSEC_PER_HOST_BUFFER  (10)
+#define PA_MAX_MSEC_PER_HOST_BUFFER  (100) /* Do not exceed unless user buffer exceeds */
+#define PA_MIN_NUM_HOST_BUFFERS      (3)
+#define PA_MAX_NUM_HOST_BUFFERS      (16)  /* OK to exceed if necessary */
+#define PA_MIN_LATENCY_MSEC          (200)
+
+#define MIN_TIMEOUT_MSEC                 (1000)
 
 #define PRINT(x) { printf x; fflush(stdout); }
 #define ERR_RPT(x) PRINT(x)
-#define DBUG(x)    /* PRINT(x) /**/
-#define DBUGX(x)   /* PRINT(x) /**/
+#define DBUG(x)  /* PRINT(x) */
+#define DBUGX(x) /* PRINT(x) */
 
-// define value of isInput passed to CoreAudio routines
-#define IS_INPUT    (true)
-#define IS_OUTPUT   (false)
+/************************************************* Definitions ********/
 
 /**************************************************************
  * Structure for internal host specific stream data.
@@ -91,165 +78,116 @@ O- FIFO between input and output callbacks if different devices, like in pa_mac.
  */
 typedef struct PaHostSoundControl
 {
-    AudioDeviceID      pahsc_AudioDeviceID;  // Must be the same for input and output for now.
     /* Input -------------- */
-    int                pahsc_BytesPerUserNativeInputBuffer; /* native buffer size in bytes per user chunk */
+    int                pahsc_BytesPerHostInputBuffer;
+    int                pahsc_BytesPerUserInputBuffer;    /* native buffer size in bytes */
     /* Output -------------- */
-    int                pahsc_BytesPerUserNativeOutputBuffer; /* native buffer size in bytes per user chunk */
+    AudioDeviceID      pahsc_OutputAudioDeviceID;
+    int                pahsc_BytesPerHostOutputBuffer;
+    int                pahsc_BytesPerUserOutputBuffer;    /* native buffer size in bytes */
+    /* Run Time -------------- */
+    PaTimestamp        pahsc_FramesPlayed;
+    long               pahsc_LastPosition;                /* used to track frames played. */
+    /* For measuring CPU utilization. */
+    // LARGE_INTEGER      pahsc_EntryCount;
+    // LARGE_INTEGER      pahsc_LastExitCount;
     /* Init Time -------------- */
+    int                pahsc_NumHostBuffers;
     int                pahsc_FramesPerHostBuffer;
-    int                pahsc_UserBuffersPerHostBuffer;    
-    /* For measuring CPU utilization. */
-    struct rusage      pahsc_EntryRusage;
-    double             pahsc_InverseMicrosPerHostBuffer; /* 1/Microseconds of real-time audio per user buffer. */
-}
-PaHostSoundControl;
+    int                pahsc_UserBuffersPerHostBuffer;
+
+    //   CRITICAL_SECTION   pahsc_StreamLock;                  /* Mutext to prevent threads from colliding. */
+    int                pahsc_StreamLockInited;
 
-/**************************************************************
- * Structure for internal extended device info.
- * 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;
+PaHostSoundControl;
 
 /************************************************* 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 PaHostDeviceInfo *sDeviceInfos = NULL;
+static int sNumDevices = 0;
+static PaDeviceInfo **sDevicePtrs = NULL;
 static int sDefaultInputDeviceID = paNoDevice;
 static int sDefaultOutputDeviceID = paNoDevice;
 static int sPaHostError = 0;
-
-static int sNumCoreDevices = 0;
-static AudioDeviceID *sCoreDeviceIDs;   // Array of Core AudioDeviceIDs
+static AudioDeviceID *sDeviceIDList;   // Array of AudioDeviceIDs
 
 static const char sMapperSuffixInput[] = " - Input";
 static const char sMapperSuffixOutput[] = " - Output";
 
-/* 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 ********/
 
+/* Convert external PA ID to an internal ID that includes WAVE_MAPPER */
+#define PaDeviceIdToWinId(id) (((id) < sNumInputDevices) ? (id - 1) : (id - sNumInputDevices - 1))
+
 /************************************************* Prototypes **********/
 
 static PaError Pa_QueryDevices( void );
 PaError PaHost_GetTotalBufferFrames( internalPortAudioStream   *past );
-
-static int PaHost_ScanDevices( Boolean isInput );
-static int PaHost_QueryDeviceInfo( PaHostDeviceInfo *hostDeviceInfo, int coreDeviceIndex, Boolean isInput );
-
-static PaDeviceID Pa_QueryDefaultInputDevice( void );
-static PaDeviceID Pa_QueryDefaultOutputDevice( void );
-static void PaHost_CalcHostBufferSize( internalPortAudioStream *past );
-
 /********************************* 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. */
-    getrusage( RUSAGE_SELF, &pahsc->pahsc_EntryRusage );
+    /* Query system timer for usage analysis and to prevent overuse of CPU. */
+    // QueryPerformanceCounter( &pahsc->pahsc_EntryCount );
 }
 
-static long SubtractTime_AminusB( struct timeval *timeA, struct timeval *timeB )
-{
-    long secs = timeA->tv_sec - timeB->tv_sec;
-    long 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 rusage currentRusage;
-    long  usecsElapsed;
-    double newUsage;
-
-#define LOWPASS_COEFFICIENT_0   (0.95)
+#if 0
+    // LARGE_INTEGER CurrentCount = { 0, 0 };
+    // LONGLONG      InsideCount;
+    // LONGLONG      TotalCount;
+    /*
+    ** Measure CPU utilization during this callback. Note that this calculation
+    ** assumes that we had the processor the whole time.
+    */
+#define LOWPASS_COEFFICIENT_0   (0.9)
 #define LOWPASS_COEFFICIENT_1   (0.99999 - LOWPASS_COEFFICIENT_0)
 
     PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;
     if( pahsc == NULL ) return;
-    
-    if( getrusage( RUSAGE_SELF, &currentRusage ) == 0 )
-    {
-        usecsElapsed = SubtractTime_AminusB( &currentRusage.ru_utime, &pahsc->pahsc_EntryRusage.ru_utime );
-        
-        /* 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);
-    }
-}
-/****************************************** END CPU UTILIZATION *******/
 
-/************************************************************************/
-static PaDeviceID Pa_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 Bail;
-    
-    // scan input devices to see which one matches this device
-    defaultDeviceID = paNoDevice;
-    for( i=LOWEST_INPUT_DEVID; i<=HIGHEST_INPUT_DEVID; i++ )
+    if( QueryPerformanceCounter( &CurrentCount ) )
     {
-        DBUG(("Pa_QueryDefaultInputDevice: i = %d, aDevId = %d\n", i, sDeviceInfos[i].audioDeviceID ));
-        if( sDeviceInfos[i].audioDeviceID == tempDeviceID )
+        if( past->past_IfLastExitValid )
         {
-            defaultDeviceID = i;
-            break;
+            InsideCount = CurrentCount.QuadPart - pahsc->pahsc_EntryCount.QuadPart;
+            TotalCount =  CurrentCount.QuadPart - pahsc->pahsc_LastExitCount.QuadPart;
+            /* Low pass filter the result because sometimes we get called several times in a row.
+             * That can cause the TotalCount to be very low which can cause the usage to appear
+             * unnaturally high. So we must filter numerator and denominator separately!!!
+             */
+            past->past_AverageInsideCount = (( LOWPASS_COEFFICIENT_0 * past->past_AverageInsideCount) +
+                                             (LOWPASS_COEFFICIENT_1 * InsideCount));
+            past->past_AverageTotalCount = (( LOWPASS_COEFFICIENT_0 * past->past_AverageTotalCount) +
+                                            (LOWPASS_COEFFICIENT_1 * TotalCount));
+            past->past_Usage = past->past_AverageInsideCount / past->past_AverageTotalCount;
         }
+        pahsc->pahsc_LastExitCount = CurrentCount;
+        past->past_IfLastExitValid = 1;
     }
-Bail:
-    return defaultDeviceID;
+#endif
 }
 
-/************************************************************************/
-static PaDeviceID Pa_QueryDefaultOutputDevice( void )
+static PaDeviceID Pa_QueryDefaultDevice( int deviceEnum )
 {
     OSStatus err = noErr;
     UInt32  count;
     int          i;
-    AudioDeviceID tempDeviceID = kAudioDeviceUnknown;
-    PaDeviceID  defaultDeviceID = paNoDevice;
+    AudioDeviceID tempDevice = kAudioDeviceUnknown;
+    PaDeviceID  defaultDeviceID;
 
     // 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);
+    count = sizeof(AudioDeviceID);
+    err = AudioHardwareGetProperty( deviceEnum,  &count, (void *) &tempDevice);
     if (err != noErr) goto Bail;
-    
-    // scan output devices to see which one matches this device
+    // find index of default device
     defaultDeviceID = paNoDevice;
-    for( i=LOWEST_OUTPUT_DEVID; i<=HIGHEST_OUTPUT_DEVID; i++ )
+    for( i=0; i<sNumDevices; i++ )
     {
-        DBUG(("Pa_QueryDefaultOutputDevice: i = %d, aDevId = %d\n", i, sDeviceInfos[i].audioDeviceID ));
-        if( sDeviceInfos[i].audioDeviceID == tempDeviceID )
+        if( sDeviceIDList[i] == tempDevice )
         {
             defaultDeviceID = i;
             break;
@@ -259,7 +197,8 @@ Bail:
     return defaultDeviceID;
 }
 
-/******************************************************************/
+/****************************************** END CPU UTILIZATION *******/
+
 static PaError Pa_QueryDevices( void )
 {
     OSStatus err = noErr;
@@ -267,43 +206,33 @@ static PaError Pa_QueryDevices( void )
     Boolean  outWritable;
     int         numBytes;
 
-    // find out how many Core Audio devices there are, if any
+    // find out how many audio devices there are, if any
     err = AudioHardwareGetPropertyInfo(kAudioHardwarePropertyDevices, &outSize, &outWritable);
     if (err != noErr)
         ERR_RPT(("Couldn't get info about list of audio devices\n"));
 
     // calculate the number of device available
-    sNumCoreDevices = outSize / sizeof(AudioDeviceID);
+    sNumDevices = outSize / sizeof(AudioDeviceID);
 
     // Bail if there aren't any devices
-    if (sNumCoreDevices < 1)
+    if (sNumDevices < 1)
         ERR_RPT(("No Devices Available\n"));
 
     // make space for the devices we are about to get
-    sCoreDeviceIDs =  (AudioDeviceID *)malloc(outSize);
+    sDeviceIDList = malloc(outSize);
 
     // get an array of AudioDeviceIDs
-    err = AudioHardwareGetProperty(kAudioHardwarePropertyDevices, &outSize, (void *)sCoreDeviceIDs);
+    err = AudioHardwareGetProperty(kAudioHardwarePropertyDevices, &outSize, (void *)sDeviceIDList);
     if (err != noErr)
         ERR_RPT(("Couldn't get list of audio device IDs\n"));
 
-    // 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;
+    /* Allocate structures to hold device info pointers. */
+    numBytes = sNumDevices * sizeof(PaDeviceInfo *);
+    sDevicePtrs = PaHost_AllocateFastMemory( numBytes );
+    if( sDevicePtrs == NULL ) return paInsufficientMemory;
 
-    // Scan all the Core Audio devices to see which support input and allocate a
-    // PaHostDeviceInfo structure for each one.
-    PaHost_ScanDevices( IS_INPUT );
-    sNumInputDevices = sNumPaDevices;
-    // Now scan all the output devices.
-    PaHost_ScanDevices( IS_OUTPUT );
-    sNumOutputDevices = sNumPaDevices - sNumInputDevices;
-
-    // Figure out which of the devices that we scanned is the default device.
-    sDefaultInputDeviceID = Pa_QueryDefaultInputDevice();
-    sDefaultOutputDeviceID = Pa_QueryDefaultOutputDevice();
+    sDefaultInputDeviceID = Pa_QueryDefaultDevice( kAudioHardwarePropertyDefaultInputDevice );
+    sDefaultOutputDeviceID = Pa_QueryDefaultDevice( kAudioHardwarePropertyDefaultOutputDevice );
 
     return paNoError;
 }
@@ -317,35 +246,45 @@ long Pa_GetHostError()
 /*************************************************************************/
 int Pa_CountDevices()
 {
-    if( sNumPaDevices <= 0 ) Pa_Initialize();
-    return sNumPaDevices;
+    if( sNumDevices <= 0 ) Pa_Initialize();
+    return sNumDevices;
 }
 
 /*************************************************************************/
+
 /* Allocate a string containing the device name. */
-static char *PaHost_DeviceNameFromID(AudioDeviceID deviceID, Boolean isInput )
+char *deviceNameFromID(AudioDeviceID deviceID )
 {
     OSStatus err = noErr;
     UInt32  outSize;
     Boolean  outWritable;
     char     *deviceName = nil;
-    
     // query size of name
-    err =  AudioDeviceGetPropertyInfo(deviceID, 0, isInput, kAudioDevicePropertyDeviceName, &outSize, &outWritable);
+    err =  AudioDeviceGetPropertyInfo(deviceID, 0, false, kAudioDevicePropertyDeviceName, &outSize, &outWritable);
     if (err == noErr)
     {
-        deviceName =  (char*)malloc( outSize + 1);
+        deviceName = malloc( outSize + 1);
         if( deviceName )
         {
-            err = AudioDeviceGetProperty(deviceID, 0, isInput, kAudioDevicePropertyDeviceName, &outSize, deviceName);
-            if (err != noErr)
-                ERR_RPT(("Couldn't get audio device name.\n"));
+            err = AudioDeviceGetProperty(deviceID, 0, false, kAudioDevicePropertyDeviceName, &outSize, deviceName);
+            // FIXME if (err == noErr)
         }
     }
 
     return deviceName;
 }
 
+/*************************************************************************/
+
+void deviceDataFormatFromID(AudioDeviceID deviceID , AudioStreamBasicDescription *desc )
+{
+    OSStatus err = noErr;
+    UInt32  outSize;
+
+    outSize = sizeof(*desc);
+    err = AudioDeviceGetProperty(deviceID, 0, false, kAudioDevicePropertyStreamFormat, &outSize, desc);
+}
+
 /*************************************************************************/
 // An AudioStreamBasicDescription is passed in to query whether or not
 // the format is supported. A kAudioDeviceUnsupportedFormatError will
@@ -354,13 +293,13 @@ static char *PaHost_DeviceNameFromID(AudioDeviceID deviceID, Boolean isInput )
 // fields set to 0 will be ignored in the query, but otherwise values
 // must match exactly.
 
-Boolean deviceDoesSupportFormat(AudioDeviceID deviceID, AudioStreamBasicDescription *desc, Boolean isInput )
+Boolean deviceDoesSupportFormat(AudioDeviceID deviceID , AudioStreamBasicDescription *desc )
 {
     OSStatus err = noErr;
     UInt32  outSize;
 
     outSize = sizeof(*desc);
-    err = AudioDeviceGetProperty(deviceID, 0, isInput, kAudioDevicePropertyStreamFormatSupported, &outSize, desc);
+    err = AudioDeviceGetProperty(deviceID, 0, false, kAudioDevicePropertyStreamFormatSupported, &outSize, desc);
 
     if (err == kAudioHardwareNoError)
         return true;
@@ -395,7 +334,7 @@ char* coreAudioErrorString (int errCode )
         str = "kAudioHardwareIllegalOperationError";
         break;
     default:
-        str = "Unknown CoreAudio Error!";
+        str = "UNKNWON ERROR!";
         break;
     }
 
@@ -403,149 +342,118 @@ char* coreAudioErrorString (int errCode )
 }
 
 /*************************************************************************
-** PaDeviceInfo structures have already been created
-** so just return the pointer.
+** If a PaDeviceInfo structure has not already been created,
+** then allocate one and fill it in for the selected device.
 **
+** We create one extra input and one extra output device for the WAVE_MAPPER.
+** [Does anyone know how to query the default device and get its name?]
 */
 const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceID id )
 {
-    if( id < 0 || id >= sNumPaDevices )
-        return NULL;
+#define NUM_STANDARDSAMPLINGRATES   3   /* 11.025, 22.05, 44.1 */
+#define NUM_CUSTOMSAMPLINGRATES     4   /* must be the same number of elements as in the array below */
+#define MAX_NUMSAMPLINGRATES        (NUM_STANDARDSAMPLINGRATES+NUM_CUSTOMSAMPLINGRATES)
 
-    return &sDeviceInfos[id].paInfo;
-}
+    PaDeviceInfo *deviceInfo;
+    AudioDeviceID    devID;
+    double *sampleRates; /* non-const ptr */
+    double possibleSampleRates[] = {8000.0, 11025.0, 22050.0, 44100.0, 48000.0, 88200.0, 96000.0};
+    int index;
+    AudioStreamBasicDescription formatDesc;
+    Boolean result;
 
-/*************************************************************************
-** Scan all of the Core Audio devices to see which support input or output.
-** Changes sNumDevices, and fills in sDeviceInfos.
-*/
-static int PaHost_ScanDevices( Boolean isInput )
-{
-    int coreDeviceIndex;
-    int result;
-    PaHostDeviceInfo  *hostDeviceInfo;
-    int numAdded = 0;
+    if( id < 0 || id >= sNumDevices )
+        return NULL;
 
-    for(  coreDeviceIndex=0; coreDeviceIndex<sNumCoreDevices; coreDeviceIndex++ )
+    if( sDevicePtrs[ id ] != NULL )
     {
-        // try to fill in next PaHostDeviceInfo
-        hostDeviceInfo = &sDeviceInfos[sNumPaDevices];
-        result = PaHost_QueryDeviceInfo( hostDeviceInfo, coreDeviceIndex, isInput );
-        DBUG(("PaHost_ScanDevices: paDevId = %d, coreDevId = %d\n", sNumPaDevices, hostDeviceInfo->audioDeviceID ));
-        if( result > 0 )
-        {
-            sNumPaDevices += 1;  // bump global counter if we got one
-            numAdded += 1;
-        }
-        else if( result < 0 ) return result;
+        return sDevicePtrs[ id ];
     }
-    return numAdded;
-}
-
-/*************************************************************************
-** 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 PaHost_QueryDeviceInfo( PaHostDeviceInfo *hostDeviceInfo, int coreDeviceIndex, Boolean isInput )
-{
-    OSErr   err;
-    int index;
-    UInt32  outSize;
-    AudioStreamBasicDescription formatDesc;
-    Boolean result;
-    AudioDeviceID    devID;
-    double *sampleRates = NULL; /* non-const ptr */
 
-    PaDeviceInfo *deviceInfo = &hostDeviceInfo->paInfo;
-    double possibleSampleRates[] = {8000.0, 11025.0, 22050.0, 44100.0, 48000.0, 88200.0, 96000.0};
-    int maxNumSampleRates = sizeof( possibleSampleRates ) / sizeof( double );
+    deviceInfo = PaHost_AllocateFastMemory( sizeof(PaDeviceInfo) );
+    if( deviceInfo == NULL ) return NULL;
 
     deviceInfo->structVersion = 1;
     deviceInfo->maxInputChannels = 0;
     deviceInfo->maxOutputChannels = 0;
     deviceInfo->numSampleRates = -1;
 
-    devID = sCoreDeviceIDs[ coreDeviceIndex ];
-    hostDeviceInfo->audioDeviceID = devID;
 
-    // Figure out supported sample rates
-    // Make room in case device supports all rates.
-    sampleRates = (double*)PaHost_AllocateFastMemory( maxNumSampleRates * sizeof(double) );
-    if( sampleRates == NULL ) return paInsufficientMemory;
+    // fill in format descriptor
+    if( id < sNumDevices )
+    {
+        devID = sDeviceIDList[ id ];
 
-    deviceInfo->sampleRates = sampleRates;
-    deviceInfo->numSampleRates = 0;
+        // Get the device name
+        deviceInfo->name = deviceNameFromID( devID );
 
-    // Loop through the possible sampling rates and check each to see if the device supports it.
-    for (index = 0; index < maxNumSampleRates; index ++)
-    {
-        memset( &formatDesc, 0, sizeof(AudioStreamBasicDescription) );
-        formatDesc.mSampleRate = possibleSampleRates[index];
-        result = deviceDoesSupportFormat( devID, &formatDesc, isInput );
+        // Figure out supported sample rates
+        // Make room in case device supports all rates.
+        sampleRates = (double*)PaHost_AllocateFastMemory( MAX_NUMSAMPLINGRATES * sizeof(double) );
+        deviceInfo->sampleRates = sampleRates;
+        deviceInfo->numSampleRates = 0;
 
-        if (result == true)
+        // Loop through the possible sampling rates and check each to see if the device supports it.
+        for (index = 0; index < MAX_NUMSAMPLINGRATES; index ++)
         {
-            deviceInfo->numSampleRates += 1;
-            *sampleRates = possibleSampleRates[index];
-            sampleRates++;
-        }
-    }
-    // If no sample rates supported, then not a very good device.
-    if( deviceInfo->numSampleRates == 0 ) goto error;
+            memset( &formatDesc, 0, sizeof(AudioStreamBasicDescription) );
+            formatDesc.mSampleRate = possibleSampleRates[index];
+            result = deviceDoesSupportFormat( devID, &formatDesc );
 
-    // Get data format info from the device.
-    outSize = sizeof(formatDesc);
-    err = AudioDeviceGetProperty(devID, 0, isInput, kAudioDevicePropertyStreamFormat, &outSize, &formatDesc);
+            if (result == true)
+            {
+                deviceInfo->numSampleRates += 1;
+                *sampleRates = possibleSampleRates[index];
+                sampleRates++;
+            }
+        }
 
-    // If no channels supported, then not a very good device.
-    if( (err != noErr) || (formatDesc.mChannelsPerFrame == 0) ) goto error;
+        // Get data format info from the device.
+        deviceDataFormatFromID(devID, &formatDesc);
 
-    if( isInput )
-    {
-        deviceInfo->maxInputChannels = formatDesc.mChannelsPerFrame;
-    }
-    else
-    {
+        deviceInfo->maxInputChannels = 0; // FIXME - Input and Output are separate devices!
         deviceInfo->maxOutputChannels = formatDesc.mChannelsPerFrame;
-    }
 
-    // FIXME - where to put current sample rate?:  formatDesc.mSampleRate
+        // FIXME - where to put current sample rate?:  formatDesc.mSampleRate
 
-    // Right now the Core Audio headers only define one formatID: LinearPCM
-    // Apparently LinearPCM must be Float32 for now.
-    switch (formatDesc.mFormatID)
-    {
-    case kAudioFormatLinearPCM:
-        deviceInfo->nativeSampleFormats = paFloat32;
-
-        // FIXME - details about the format are in these flags.
-        // formatDesc.mFormatFlags
-
-        // here are the possibilities
-        // kLinearPCMFormatFlagIsFloat   // set for floating point, clear for integer
-        // kLinearPCMFormatFlagIsBigEndian  // set for big endian, clear for little
-        // kLinearPCMFormatFlagIsSignedInteger // set for signed integer, clear for unsigned integer,
-        //    only valid if kLinearPCMFormatFlagIsFloat is clear
-        // kLinearPCMFormatFlagIsPacked   // set if the sample bits are packed as closely together as possible,
-        //    clear if they are high or low aligned within the channel
-        // kLinearPCMFormatFlagIsAlignedHigh  // set if the sample bits are placed
-        break;
+        // Right now the Core Audio headers only define one formatID: LinearPCM
+        // Apparently LinearPCM must be Float32 for now.
+        // FIXME -
+        switch (formatDesc.mFormatID)
+        {
+        case kAudioFormatLinearPCM:
+            deviceInfo->nativeSampleFormats = paFloat32;
+
+            // FIXME - details about the format are in these flags.
+            // formatDesc.mFormatFlags
+
+            // here are the possibilities
+            // kLinearPCMFormatFlagIsFloat   // set for floating point, clear for integer
+            // kLinearPCMFormatFlagIsBigEndian  // set for big endian, clear for little
+            // kLinearPCMFormatFlagIsSignedInteger // set for signed integer, clear for unsigned integer,
+            //    only valid if kLinearPCMFormatFlagIsFloat is clear
+            // kLinearPCMFormatFlagIsPacked   // set if the sample bits are packed as closely together as possible,
+            //    clear if they are high or low aligned within the channel
+            // kLinearPCMFormatFlagIsAlignedHigh  // set if the sample bits are placed
+
+            break;
+        default:
+            deviceInfo->nativeSampleFormats = paFloat32;  // FIXME
+            break;
+        }
 
-    default:
-        deviceInfo->nativeSampleFormats = paFloat32;  // FIXME
-        break;
     }
 
-    // Get the device name
-    deviceInfo->name = PaHost_DeviceNameFromID( devID, isInput );
-    return 1;
+    sDevicePtrs[ id ] = deviceInfo;
+    return deviceInfo;
 
-error:
-    if( sampleRates != NULL ) free( sampleRates );
-    return 0;
+    /* FIXME
+    error:
+        free( sampleRates );
+        free( deviceInfo );
+    */
+
+    return NULL;
 }
 
 /*************************************************************************
@@ -583,7 +491,7 @@ static PaDeviceID PaHost_GetEnvDefaultDeviceID( char *envName )
 
 static PaError Pa_MaybeQueryDevices( void )
 {
-    if( sNumPaDevices == 0 )
+    if( sNumDevices == 0 )
     {
         return Pa_QueryDevices();
     }
@@ -625,6 +533,9 @@ PaDeviceID Pa_GetDefaultOutputDeviceID( void )
 
 PaError PaHost_Init( void )
 {
+#if PA_SIMULATE_UNDERFLOW
+    PRINT(("WARNING - Underflow Simulation Enabled - Expect a Big Glitch!!!\n"));
+#endif
     return Pa_MaybeQueryDevices();
 }
 
@@ -636,8 +547,10 @@ static PaError Pa_TimeSlice( internalPortAudioStream   *past, const AudioBufferL
                              AudioBufferList*  outOutputData )
 {
     PaError           result = 0;
-    char             *inputNativeBufferfPtr = NULL;
-    char             *outputNativeBufferfPtr = NULL;
+    char             *inBufPtr;
+    char             *outBufPtr;
+    int               gotInput = 0;
+    int               gotOutput = 0;
     int               i;
     int               buffersProcessed = 0;
     int               done = 0;
@@ -646,6 +559,13 @@ static PaError Pa_TimeSlice( internalPortAudioStream   *past, const AudioBufferL
 
     past->past_NumCallbacks += 1;
 
+#if PA_SIMULATE_UNDERFLOW
+    if(gUnderCallbackCounter++ == UNDER_SLEEP_AT)
+    {
+        Sleep(UNDER_SLEEP_FOR);
+    }
+#endif
+
 #if PA_TRACE_RUN
     AddTraceMessage("Pa_TimeSlice: past_NumCallbacks ", past->past_NumCallbacks );
 #endif
@@ -653,15 +573,20 @@ static PaError Pa_TimeSlice( internalPortAudioStream   *past, const AudioBufferL
     Pa_StartUsageCalculation( past );
 
     /* If we are using output, then we need an empty output buffer. */
+    gotOutput = 0;
     if( past->past_NumOutputChannels > 0 )
     {
-        outputNativeBufferfPtr =  (char*)outOutputData->mBuffers[0].mData;
+        outBufPtr =  outOutputData->mBuffers[0].mData,
+                     gotOutput = 1;
     }
 
     /* If we are using input, then we need a full input buffer. */
+    gotInput = 0;
+    inBufPtr = NULL;
     if(  past->past_NumInputChannels > 0  )
     {
-        inputNativeBufferfPtr = (char*)inInputData->mBuffers[0].mData;
+        inBufPtr = inInputData->mBuffers[0].mData,
+                   gotInput = 1;
     }
 
     buffersProcessed += 1;
@@ -671,21 +596,21 @@ static PaError Pa_TimeSlice( internalPortAudioStream   *past, const AudioBufferL
     {
         if( done )
         {
-            if( outputNativeBufferfPtr )
+            if( gotOutput )
             {
                 /* Clear remainder of wave buffer if we are waiting for stop. */
                 AddTraceMessage("Pa_TimeSlice: zero rest of wave buffer ", i );
-                memset( outputNativeBufferfPtr, 0, pahsc->pahsc_BytesPerUserNativeOutputBuffer );
+                memset( outBufPtr, 0, pahsc->pahsc_BytesPerUserOutputBuffer );
             }
         }
         else
         {
-            /* Convert 32 bit native data to user data and call user routine. */
-            result = PaConvert_Process( past, inputNativeBufferfPtr, outputNativeBufferfPtr );
+            /* Convert 16 bit native data to user data and call user routine. */
+            result = Pa_CallConvertFloat32( past, (float *) inBufPtr, (float *) outBufPtr );
             if( result != 0) done = 1;
         }
-        if( inputNativeBufferfPtr ) inputNativeBufferfPtr += pahsc->pahsc_BytesPerUserNativeInputBuffer;
-        if( outputNativeBufferfPtr) outputNativeBufferfPtr += pahsc->pahsc_BytesPerUserNativeOutputBuffer;
+        if( gotInput ) inBufPtr += pahsc->pahsc_BytesPerUserInputBuffer;
+        if( gotOutput) outBufPtr += pahsc->pahsc_BytesPerUserOutputBuffer;
     }
 
     Pa_EndUsageCalculation( past );
@@ -697,10 +622,7 @@ static PaError Pa_TimeSlice( internalPortAudioStream   *past, const AudioBufferL
     return (result != 0) ? result : done;
 }
 
-OSStatus appIOProc (AudioDeviceID  inDevice, const AudioTimeStamp*  inNow,
-                    const AudioBufferList*  inInputData, const AudioTimeStamp*  inInputTime,
-                    AudioBufferList*  outOutputData, const AudioTimeStamp* inOutputTime,
-                    void* contextPtr)
+OSStatus appIOProc (AudioDeviceID  inDevice, const AudioTimeStamp*  inNow, const AudioBufferList*  inInputData, const AudioTimeStamp*  inInputTime, AudioBufferList*  outOutputData, const AudioTimeStamp* inOutputTime, void* contextPtr)
 {
 
     PaError      result = 0;
@@ -709,7 +631,7 @@ OSStatus appIOProc (AudioDeviceID  inDevice, const AudioTimeStamp*  inNow,
     past = (internalPortAudioStream *) contextPtr;
     pahsc = (PaHostSoundControl *) past->past_DeviceData;
 
-// printf("Num input Buffers: %d; Num output Buffers: %d.\n", inInputData->mNumberBuffers,     outOutputData->mNumberBuffers);
+    // Just Curious: printf("Num input Buffers: %d; Num output Buffers: %d.\n", inInputData->mNumberBuffers, outOutputData->mNumberBuffers);
 
     /* Has someone asked us to abort by calling Pa_AbortStream()? */
     if( past->past_StopNow )
@@ -726,12 +648,6 @@ OSStatus appIOProc (AudioDeviceID  inDevice, const AudioTimeStamp*  inNow,
     }
     else
     {
-        /* use time stamp from CoreAudio if valid */
-        if( inOutputTime->mFlags & kAudioTimeStampSampleTimeValid) 
-        {
-            past->past_FrameCount = inOutputTime->mSampleTime;
-        }
-        
         /* Process full input buffer and fill up empty output buffers. */
         if( (result = Pa_TimeSlice( past, inInputData, outOutputData )) != 0)
         {
@@ -749,7 +665,6 @@ OSStatus appIOProc (AudioDeviceID  inDevice, const AudioTimeStamp*  inNow,
     return result;
 }
 
-#if 0
 static int PaHost_CalcTimeOut( internalPortAudioStream *past )
 {
     /* Calculate timeOut longer than longest time it could take to play all buffers. */
@@ -757,150 +672,59 @@ static int PaHost_CalcTimeOut( internalPortAudioStream *past )
     if( timeOut < MIN_TIMEOUT_MSEC ) timeOut = MIN_TIMEOUT_MSEC;
     return timeOut;
 }
-#endif
-
-
-/*******************************************************************/
-/* Attempt to set device sample rate. */
-static PaError PaHost_SetSampleRate( AudioDeviceID devID, Boolean isInput, double sampleRate )
-{
-    AudioStreamBasicDescription formatDesc;
-    OSStatus err;
-    memset( &formatDesc, 0, sizeof(AudioStreamBasicDescription) );
-    formatDesc.mSampleRate = sampleRate;
-    err = AudioDeviceSetProperty( devID, 0, 0,
-        isInput, kAudioDevicePropertyStreamFormat, sizeof(formatDesc), &formatDesc);
-
-    if (err != kAudioHardwareNoError) return paInvalidSampleRate;
-       else return paNoError;
-}
 
 /*******************************************************************/
 PaError PaHost_OpenInputStream( internalPortAudioStream   *past )
 {
-    PaHostSoundControl *pahsc;
-    const PaHostDeviceInfo *hostDeviceInfo;
     PaError          result = paNoError;
-    UInt32           bytesPerHostBuffer;
-    UInt32           dataSize;
-    OSStatus         err = noErr;
+    PaHostSoundControl *pahsc;
     int              bytesPerInputFrame;
+    const PaDeviceInfo  *pad;
 
     pahsc = (PaHostSoundControl *) past->past_DeviceData;
-    
-    DBUG(("PaHost_OpenStream: deviceID = 0x%x\n", past->past_InputDeviceID));
-    if( (past->past_InputDeviceID < LOWEST_INPUT_DEVID) ||
-        (past->past_InputDeviceID > HIGHEST_INPUT_DEVID) )
-    {
-        return paInvalidDeviceId;
-    }
-    hostDeviceInfo = &sDeviceInfos[past->past_InputDeviceID];
-
-    /* Try to set sample rate. */
-    result = PaHost_SetSampleRate( hostDeviceInfo->audioDeviceID, IS_INPUT, past->past_SampleRate );
-       if( result != paNoError ) return result;
-
-    if( past->past_NumInputChannels != hostDeviceInfo->paInfo.maxInputChannels )
-    {
-#if 1
-        return paInvalidChannelCount; // FIXME - how support mono?
-#else
-FIXME - should this be set on a stream basis? Is it possible to change?
-    /* Attempt to set number of channels. */ 
-        AudioStreamBasicDescription formatDesc;
-        OSStatus err;
-        memset( &formatDesc, 0, sizeof(AudioStreamBasicDescription) );
-        formatDesc.mChannelsPerFrame = past->past_NumInputChannels;
-        
-        err = AudioDeviceSetProperty( hostDeviceInfo->audioDeviceID, 0, 0,
-            IS_INPUT, kAudioDevicePropertyStreamFormat, sizeof(formatDesc), &formatDesc);
-        if (err != kAudioHardwareNoError)
-        {
-            result = paInvalidChannelCount;
-            goto error;
-        }
-#endif
-    }
-
-    // calculate native buffer sizes in bytes
-    bytesPerInputFrame = Pa_GetSampleSize(paFloat32) * past->past_NumInputChannels;
-    pahsc->pahsc_BytesPerUserNativeInputBuffer = past->past_FramesPerUserBuffer * bytesPerInputFrame;
-    bytesPerHostBuffer = pahsc->pahsc_FramesPerHostBuffer * bytesPerInputFrame;
-
-    // Change the bufferSize of the device! Is this per device or just for our stream?
-    dataSize = sizeof(UInt32);
-    err = AudioDeviceSetProperty( hostDeviceInfo->audioDeviceID, 0, 0, IS_INPUT,
-                                  kAudioDevicePropertyBufferSize, dataSize, &bytesPerHostBuffer);
-    if( err != noErr )
-    {
-        ERR_RPT(("Could not force buffer size!"));
-        result = paHostError;
-        goto error;
-    }
 
-    // setup conversion procedure
-    result = PaConvert_SetupInput( past, paFloat32 );
-
-    return result;
+    DBUG(("PaHost_OpenStream: deviceID = 0x%x\n", past->past_InputDeviceID));
+    pad = Pa_GetDeviceInfo( past->past_InputDeviceID );
+    if( pad == NULL ) return paInternalError;
 
-error:
+    bytesPerInputFrame = Pa_GetSampleSize(pad->nativeSampleFormats) * past->past_NumInputChannels;
+    pahsc->pahsc_BytesPerUserInputBuffer = past->past_FramesPerUserBuffer * bytesPerInputFrame;
+    pahsc->pahsc_BytesPerHostInputBuffer = pahsc->pahsc_UserBuffersPerHostBuffer * pahsc->pahsc_BytesPerUserInputBuffer;
+    // FIXME
     return result;
 }
 
 /*******************************************************************/
 PaError PaHost_OpenOutputStream( internalPortAudioStream   *past )
 {
-    PaHostSoundControl *pahsc;
-    const PaHostDeviceInfo *hostDeviceInfo;
     PaError          result = paNoError;
+    PaHostSoundControl *pahsc;
+    const PaDeviceInfo *pad;
     UInt32           bytesPerHostBuffer;
-    UInt32           dataSize;
+    UInt32   dataSize;
+    UInt32   hardwareLatency = -1;
+    Boolean   writeable = false;
     OSStatus         err = noErr;
     int              bytesPerOutputFrame;
-    
+
     pahsc = (PaHostSoundControl *) past->past_DeviceData;
-    
+
     DBUG(("PaHost_OpenStream: 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];
+    pad = Pa_GetDeviceInfo( past->past_OutputDeviceID );
+    if( pad == NULL ) return paInternalError;
 
-    /* Try to set sample rate. */
-    result = PaHost_SetSampleRate( hostDeviceInfo->audioDeviceID, IS_OUTPUT, past->past_SampleRate );
-       if( result != paNoError ) return result;
+    pahsc->pahsc_OutputAudioDeviceID = sDeviceIDList[past->past_OutputDeviceID];
 
-    if( past->past_NumOutputChannels != hostDeviceInfo->paInfo.maxOutputChannels )
-    {
-#if 1
-        return paInvalidChannelCount; // FIXME - how support mono?
-#else
-    /* Attempt to set number of channels. */ 
-        AudioStreamBasicDescription formatDesc;
-        OSStatus err;
-        memset( &formatDesc, 0, sizeof(AudioStreamBasicDescription) );
-        formatDesc.mChannelsPerFrame = past->past_NumOutputChannels;
-        err = AudioDeviceSetProperty( hostDeviceInfo->audioDeviceID, 0, 0,
-            IS_OUTPUT, kAudioDevicePropertyStreamFormat, sizeof(formatDesc), &formatDesc);
-
-        if (err != kAudioHardwareNoError)
-        {
-            result = paInvalidChannelCount;
-            goto error;
-        }
-#endif
-    }
+    bytesPerOutputFrame = Pa_GetSampleSize(pad->nativeSampleFormats) * past->past_NumOutputChannels;
+    pahsc->pahsc_BytesPerUserOutputBuffer = past->past_FramesPerUserBuffer * bytesPerOutputFrame;
+    pahsc->pahsc_BytesPerHostOutputBuffer = pahsc->pahsc_UserBuffersPerHostBuffer * pahsc->pahsc_BytesPerUserOutputBuffer;
 
-    // calculate buffer sizes in bytes
-    bytesPerOutputFrame = Pa_GetSampleSize(paFloat32) * past->past_NumOutputChannels;
-    pahsc->pahsc_BytesPerUserNativeOutputBuffer = past->past_FramesPerUserBuffer * bytesPerOutputFrame;
-    bytesPerHostBuffer = pahsc->pahsc_FramesPerHostBuffer * bytesPerOutputFrame;
+    // FIXME - force host buffer to user size
 
-    // Change the bufferSize of the device! Is this per device or just for our stream?
-    dataSize = sizeof(bytesPerHostBuffer);
-    err = AudioDeviceSetProperty( hostDeviceInfo->audioDeviceID, 0, 0, IS_OUTPUT,
+    // change the bufferSize of the device
+    bytesPerHostBuffer = past->past_OutputBufferSize; // FIXME
+    dataSize = sizeof(UInt32);
+    err = AudioDeviceSetProperty( pahsc->pahsc_OutputAudioDeviceID, 0, 0, false,
                                   kAudioDevicePropertyBufferSize, dataSize, &bytesPerHostBuffer);
     if( err != noErr )
     {
@@ -908,10 +732,25 @@ PaError PaHost_OpenOutputStream( internalPortAudioStream   *past )
         result = paHostError;
         goto error;
     }
-    
-    // setup conversion procedure
-    result = PaConvert_SetupOutput( past, paFloat32 );
-    
+
+    // FIXME -- this isn't working for some reason.  I can't figure out what the error code is.
+    dataSize = sizeof(UInt32);
+    err = AudioDeviceGetProperty(pahsc->pahsc_OutputAudioDeviceID, 0, false, kAudioDevicePropertyLatency, &dataSize, &writeable);
+    if( err != noErr )
+    {
+        PRINT(("A CoreAudio error occurred: %s.\n", coreAudioErrorString( err ) ));
+    }
+
+    err = AudioDeviceGetProperty(pahsc->pahsc_OutputAudioDeviceID, 0, false, kAudioDevicePropertyLatency, &dataSize, (void *)&hardwareLatency);
+    if ( err != noErr )
+    {
+        PRINT(("A CoreAudio error occurred: %s.\n", coreAudioErrorString( err ) ));
+    }
+    else
+    {
+        PRINT(("Output Stream Hardware Latency = %d frames.\n", hardwareLatency ));
+    }
+
     return result;
 
 error:
@@ -922,38 +761,92 @@ error:
 PaError PaHost_GetTotalBufferFrames( internalPortAudioStream   *past )
 {
     PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;
-    return pahsc->pahsc_FramesPerHostBuffer;
+    return pahsc->pahsc_NumHostBuffers * pahsc->pahsc_FramesPerHostBuffer;
 }
 
 
 /*******************************************************************
-* Determine how many User Buffers we can put into our CoreAudio stream buffer.
-* Uses:
-*    past->past_FramesPerUserBuffer, etc.
-* Sets:
-*    past->past_NumUserBuffers
-*    pahsc->pahsc_UserBuffersPerHostBuffer
-*    pahsc->pahsc_FramesPerHostBuffer
+* Determine number of WAVE Buffers
+* and how many User Buffers we can put into each WAVE buffer.
 */
-static void PaHost_CalcHostBufferSize( internalPortAudioStream *past )
+void PaHost_CalcNumHostBuffers( internalPortAudioStream *past )
 {
-    PaHostSoundControl *pahsc = ( PaHostSoundControl *)past->past_DeviceData;
-    unsigned int  minNumUserBuffers;
-
-    // Determine number of user buffers based on minimum latency.
-    minNumUserBuffers = Pa_GetMinNumBuffers( past->past_FramesPerUserBuffer, past->past_SampleRate );
-    // Compare to user requested number in user wants more than the minimum.
-    past->past_NumUserBuffers = ( minNumUserBuffers > past->past_NumUserBuffers ) ?
-                                minNumUserBuffers : past->past_NumUserBuffers;
+    PaHostSoundControl *pahsc = past->past_DeviceData;
+    unsigned int  minNumBuffers;
+    int           minFramesPerHostBuffer;
+    int           maxFramesPerHostBuffer;
+    int           minTotalFrames;
+    int           userBuffersPerHostBuffer;
+    int           framesPerHostBuffer;
+    int           numHostBuffers;
+
+    /* Calculate minimum and maximum sizes based on timing and sample rate. */
+    minFramesPerHostBuffer = (int) (PA_MIN_MSEC_PER_HOST_BUFFER * past->past_SampleRate / 1000.0);
+    minFramesPerHostBuffer = (minFramesPerHostBuffer + 7) & ~7;
+    DBUG(("PaHost_CalcNumHostBuffers: minFramesPerHostBuffer = %d\n", minFramesPerHostBuffer ));
+
+    maxFramesPerHostBuffer = (int) (PA_MAX_MSEC_PER_HOST_BUFFER * past->past_SampleRate / 1000.0);
+    maxFramesPerHostBuffer = (maxFramesPerHostBuffer + 7) & ~7;
+    DBUG(("PaHost_CalcNumHostBuffers: maxFramesPerHostBuffer = %d\n", maxFramesPerHostBuffer ));
+
+    /* Determine number of user buffers based on minimum latency. */
+    minNumBuffers = Pa_GetMinNumBuffers( 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 ));
 
-    // For CoreAudio, we only have one Host buffer, so...
-    pahsc->pahsc_UserBuffersPerHostBuffer = past->past_NumUserBuffers;
-    // Calculate size of CoreAudio buffer.
-    pahsc->pahsc_FramesPerHostBuffer = past->past_FramesPerUserBuffer * past->past_NumUserBuffers;
+    minTotalFrames = past->past_NumUserBuffers * past->past_FramesPerUserBuffer;
+
+    /* We cannot make the WAVE buffers too small because they may not get serviced quickly enough. */
+    if( (int) past->past_FramesPerUserBuffer < minFramesPerHostBuffer )
+    {
+        userBuffersPerHostBuffer =
+            (minFramesPerHostBuffer + past->past_FramesPerUserBuffer - 1) /
+            past->past_FramesPerUserBuffer;
+    }
+    else
+    {
+        userBuffersPerHostBuffer = 1;
+    }
+
+
+    framesPerHostBuffer = past->past_FramesPerUserBuffer * userBuffersPerHostBuffer;
+    /* Calculate number of WAVE buffers needed. Round up to cover minTotalFrames. */
+    numHostBuffers = (minTotalFrames + framesPerHostBuffer - 1) / framesPerHostBuffer;
+
+    /* Make sure we have anough WAVE buffers. */
+    if( numHostBuffers < PA_MIN_NUM_HOST_BUFFERS)
+    {
+        numHostBuffers = PA_MIN_NUM_HOST_BUFFERS;
+    }
+    else if( (numHostBuffers > PA_MAX_NUM_HOST_BUFFERS) &&
+             ((int) past->past_FramesPerUserBuffer < (maxFramesPerHostBuffer/2) ) )
+    {
+        /* If we have too many WAVE buffers, try to put more user buffers in a wave buffer. */
+        while(numHostBuffers > PA_MAX_NUM_HOST_BUFFERS)
+        {
+            userBuffersPerHostBuffer += 1;
+            framesPerHostBuffer = past->past_FramesPerUserBuffer * userBuffersPerHostBuffer;
+            numHostBuffers = (minTotalFrames + framesPerHostBuffer - 1) / framesPerHostBuffer;
+            /* If we have gone too far, back up one. */
+            if( (framesPerHostBuffer > maxFramesPerHostBuffer) ||
+                    (numHostBuffers < PA_MAX_NUM_HOST_BUFFERS) )
+            {
+                userBuffersPerHostBuffer -= 1;
+                framesPerHostBuffer = past->past_FramesPerUserBuffer * userBuffersPerHostBuffer;
+                numHostBuffers = (minTotalFrames + framesPerHostBuffer - 1) / framesPerHostBuffer;
+                break;
+            }
+        }
+    }
+
+    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 ));
 }
 
 /*******************************************************************/
@@ -972,33 +865,21 @@ PaError PaHost_OpenStream( internalPortAudioStream   *past )
     memset( pahsc, 0, sizeof(PaHostSoundControl) );
     past->past_DeviceData = (void *) pahsc;
 
-    // If we are using both input and out, then they must be on the same CoreAudio device,
-    // until we implement a FIFO between two devices.
-    if( (past->past_OutputDeviceID != paNoDevice) && (past->past_InputDeviceID != paNoDevice) )
-    {
-        AudioDeviceID inputID = sDeviceInfos[past->past_InputDeviceID].audioDeviceID;
-        AudioDeviceID outputID = sDeviceInfos[past->past_OutputDeviceID].audioDeviceID;
-        if( inputID != outputID )
-        {
-            ERR_RPT(("PortAudio: input and output must use same CoreAudio device!\n"));
-            return paInvalidDeviceId;
-        }
-    }
+    /* Figure out how user buffers fit into WAVE buffers. */
+    // FIXME - just force for now
 
-    PaHost_CalcHostBufferSize( past );
+    pahsc->pahsc_UserBuffersPerHostBuffer = 1;
+    pahsc->pahsc_FramesPerHostBuffer = past->past_FramesPerUserBuffer;
+    pahsc->pahsc_NumHostBuffers = 2; // FIXME - dunno?!
 
     {
         int msecLatency = (int) ((PaHost_GetTotalBufferFrames(past) * 1000) / past->past_SampleRate);
-        PRINT(("PortAudio on OS X - Latency = %d frames, %d msec\n", PaHost_GetTotalBufferFrames(past), msecLatency ));
+        PRINT(("PortAudio on OSX - Latency = %d frames, %d msec\n", PaHost_GetTotalBufferFrames(past), msecLatency ));
     }
-    
-    /* Setup constants for CPU load measurement. */
-    pahsc->pahsc_InverseMicrosPerHostBuffer = past->past_SampleRate / (1000000.0 *     pahsc->pahsc_FramesPerHostBuffer);
 
     /* ------------------ OUTPUT */
     if( (past->past_OutputDeviceID != paNoDevice) && (past->past_NumOutputChannels > 0) )
     {
-        pahsc->pahsc_AudioDeviceID = sDeviceInfos[past->past_OutputDeviceID].audioDeviceID;
         result = PaHost_OpenOutputStream( past );
         if( result < 0 ) goto error;
     }
@@ -1006,7 +887,6 @@ PaError PaHost_OpenStream( internalPortAudioStream   *past )
     /* ------------------ INPUT */
     if( (past->past_InputDeviceID != paNoDevice) && (past->past_NumInputChannels > 0) )
     {
-        pahsc->pahsc_AudioDeviceID = sDeviceInfos[past->past_InputDeviceID].audioDeviceID;
         result = PaHost_OpenInputStream( past );
         if( result < 0 ) goto error;
     }
@@ -1021,83 +901,118 @@ error:
 /*************************************************************************/
 PaError PaHost_StartOutput( internalPortAudioStream *past )
 {
-    return 0;
+    PaHostSoundControl *pahsc;
+    PaError          result = paNoError;
+    OSStatus  err = noErr;
+
+
+    pahsc = (PaHostSoundControl *) past->past_DeviceData;
+
+    if( past->past_OutputDeviceID != paNoDevice )
+    {
+        // Associate an IO proc with the device and pass a pointer to the audio data context
+        err = AudioDeviceAddIOProc(pahsc->pahsc_OutputAudioDeviceID, (AudioDeviceIOProc)appIOProc, past);
+        if (err != noErr) goto error;
+
+        // start playing sound through the device
+        err = AudioDeviceStart(pahsc->pahsc_OutputAudioDeviceID, (AudioDeviceIOProc)appIOProc);
+        if (err != noErr) goto error;
+    }
+
+error:
+    return result;
 }
 
 /*************************************************************************/
 PaError PaHost_StartInput( internalPortAudioStream *past )
 {
-    return 0;
+    PaError          result = paNoError;
+    PaHostSoundControl *pahsc;
+    pahsc = (PaHostSoundControl *) past->past_DeviceData;
+
+    if( past->past_InputDeviceID != paNoDevice )
+    {
+        // FIXME
+    }
+    return result;
 }
 
 /*************************************************************************/
 PaError PaHost_StartEngine( internalPortAudioStream *past )
 {
-    OSStatus            err = noErr;
     PaError             result = paNoError;
     PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;
 
+#if PA_USE_TIMER_CALLBACK
+    int                 resolution;
+    int                 bufsPerTimerCallback;
+    int                 msecPerBuffer;
+#endif /* PA_USE_TIMER_CALLBACK */
+
     past->past_StopSoon = 0;
     past->past_StopNow = 0;
     past->past_IsActive = 1;
-    
-    // Associate an IO proc with the device and pass a pointer to the audio data context
-    err = AudioDeviceAddIOProc(pahsc->pahsc_AudioDeviceID, (AudioDeviceIOProc)appIOProc, past);
-    if (err != noErr) goto error;
-
-    // start playing sound through the device
-    err = AudioDeviceStart(pahsc->pahsc_AudioDeviceID, (AudioDeviceIOProc)appIOProc);
-    if (err != noErr) goto error;
-    return result;
+    pahsc->pahsc_FramesPlayed = 0.0;
+    pahsc->pahsc_LastPosition = 0;
 
 #if PA_TRACE_START_STOP
     AddTraceMessage( "PaHost_StartEngine: TimeSlice() returned ", result );
 #endif
-
-error:
-    return paHostError; // FIXME - save host error
+    return result;
 }
 
 /*************************************************************************/
 PaError PaHost_StopEngine( internalPortAudioStream *past, int abort )
 {
-    OSStatus  err = noErr;
+    int timeOut;
     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->pahsc_AudioDeviceID, (AudioDeviceIOProc)appIOProc);
-    if (err != noErr) goto Bail;
-
-    err = AudioDeviceRemoveIOProc(pahsc->pahsc_AudioDeviceID, (AudioDeviceIOProc)appIOProc);
-    if (err != noErr) goto Bail;
+    timeOut = PaHost_CalcTimeOut( past );
+    past->past_IsActive = 0;
 
     return paNoError;
-
-Bail:
-    return paHostError; // FIXME - save err
 }
 
 /*************************************************************************/
 PaError PaHost_StopInput( internalPortAudioStream *past, int abort )
 {
+    PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;
+    if( pahsc == NULL ) return paNoError;
+    (void) abort;
+
+    // FIXME
     return paNoError;
 }
 
 /*************************************************************************/
 PaError PaHost_StopOutput( internalPortAudioStream *past, int abort )
 {
+    PaHostSoundControl *pahsc;
+    pahsc = (PaHostSoundControl *) past->past_DeviceData;
+    if( pahsc == NULL ) return paNoError;
+    (void) abort;
+
+#if PA_TRACE_START_STOP
+    AddTraceMessage( "PaHost_StopOutput: pahsc_HWaveOut ", (int) pahsc->pahsc_HWaveOut );
+#endif
+
+    // FIXME   if( pahsc->pahsc_OutputAudioDeviceID != ??? )
+    {
+        OSStatus  err = noErr;
+
+        err = AudioDeviceStop(pahsc->pahsc_OutputAudioDeviceID, (AudioDeviceIOProc)appIOProc);
+        if (err != noErr) goto Bail;
+
+        err = AudioDeviceRemoveIOProc(pahsc->pahsc_OutputAudioDeviceID, (AudioDeviceIOProc)appIOProc);
+        if (err != noErr) goto Bail;
+    }
+Bail:
     return paNoError;
 }
 
@@ -1113,6 +1028,9 @@ PaError PaHost_CloseStream( internalPortAudioStream   *past )
 #if PA_TRACE_START_STOP
     AddTraceMessage( "PaHost_CloseStream: pahsc_HWaveOut ", (int) pahsc->pahsc_HWaveOut );
 #endif
+    /* Free data and device for output. */
+
+    /* Free data and device for input. */
 
     free( pahsc );
     past->past_DeviceData = NULL;
@@ -1127,52 +1045,29 @@ PaError PaHost_CloseStream( internalPortAudioStream   *past )
 **
 **    set PA_MIN_LATENCY_MSEC=200
 **
-** in the cshrc file.
+** 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.
 */
 #define PA_LATENCY_ENV_NAME  ("PA_MIN_LATENCY_MSEC")
 
-#if 1
-int Pa_GetMinNumBuffers( int framesPerBuffer, double framesPerSecond )
+int Pa_GetMinNumBuffers( int framesPerBuffer, double sampleRate )
 {
-    int minBuffers;
-    int denominator;
-    int minLatencyMsec = PA_MIN_LATENCY_MSEC;
-    char *minLatencyText = getenv(PA_LATENCY_ENV_NAME);
-    if( minLatencyText != NULL )
+    int       minLatencyMsec = 0;
+    double    msecPerBuffer = (1000.0 * framesPerBuffer) / sampleRate;
+    int       minBuffers;
+
+    /* Let user determine minimal latency by setting environment variable. */
     {
-        PRINT(("PA_MIN_LATENCY_MSEC = %s\n", minLatencyText ));
-        minLatencyMsec = atoi( minLatencyText );
-        if( minLatencyMsec < 1 ) minLatencyMsec = 1;
-        else if( minLatencyMsec > 5000 ) minLatencyMsec = 5000;
+        minLatencyMsec = PA_MIN_LATENCY_MSEC;
     }
 
-    denominator =  1000.0 * framesPerBuffer;
-    minBuffers = (int) (((minLatencyMsec * framesPerSecond) + denominator - 1) / denominator );
-    if( minBuffers < 1 ) minBuffers = 1;
-    return minBuffers;
-}
-#else
-/*************************************************************************
-** Determine minimum number of buffers required for this host based
-** on minimum latency. 
-*/
-int Pa_GetMinNumBuffers( int framesPerUserBuffer, double sampleRate )
-{
-    int   minUserBuffers;
-    int   minFramesPerHostBuffer;
-
-    // Calculate minimum and maximum sizes based on timing and sample rate.
-    minFramesPerHostBuffer = (int) (PA_MIN_LATENCY_MSEC * sampleRate / 1000.0);
-    // round up to nearest multiple of 8
-    minFramesPerHostBuffer = (minFramesPerHostBuffer + 7) & ~7;
-    DBUG(("Pa_GetMinNumBuffers: minFramesPerHostBuffer = %d\n", minFramesPerHostBuffer ));
+    DBUG(("PA - Minimum Latency set to %d msec!\n", minLatencyMsec ));
+    minBuffers = (int) (1.0 + ((double)minLatencyMsec / msecPerBuffer));
+    if( minBuffers < 2 ) minBuffers = 2;
 
-    minUserBuffers = (minFramesPerHostBuffer + framesPerUserBuffer - 1) / framesPerUserBuffer;
-    if( minUserBuffers < 1 ) minUserBuffers = 1;
-
-    return minUserBuffers;
+    return minBuffers;
 }
-#endif
 
 /*************************************************************************
 ** Cleanup device info.
@@ -1181,32 +1076,41 @@ PaError PaHost_Term( void )
 {
     int i;
 
-    if( sDeviceInfos != NULL )
+    if( sNumDevices > 0 )
     {
-        for( i=0; i<sNumPaDevices; i++ )
+
+        if( sDevicePtrs != NULL )
         {
-            if( sDeviceInfos[i].paInfo.name != NULL ) free( (char*)sDeviceInfos[i].paInfo.name );
-            if( sDeviceInfos[i].paInfo.sampleRates != NULL ) free( (void*)sDeviceInfos[i].paInfo.sampleRates );
+
+            for( i=0; i<sNumDevices; i++ )
+            {
+                if( sDevicePtrs[i] != NULL )
+                {
+
+                    free( (char*)sDevicePtrs[i]->name );
+                    free( (void*)sDevicePtrs[i]->sampleRates );
+                    free( sDevicePtrs[i] );
+                }
+            }
+
+            free( sDevicePtrs );
+            sDevicePtrs = NULL;
         }
-        free( sDeviceInfos );
-        sDeviceInfos = NULL;
-    }
 
-    sNumPaDevices = 0;
+        sNumDevices = 0;
+    }
     return paNoError;
 }
 
 /*************************************************************************/
 void Pa_Sleep( long msec )
 {
-#if 0
-    struct timeval timeout;
-    timeout.tv_sec = msec / 1000;
-       timeout.tv_usec = (msec % 1000) * 1000;
-       select( 0, NULL, NULL, NULL, &timeout );
-#else
+    /*       struct timeval timeout;
+           timeout.tv_sec = msec / 1000;
+           timeout.tv_usec = (msec % 1000) * 1000;
+           select( 0, NULL, NULL, NULL, &timeout );
+    */
     usleep( msec * 1000 );
-#endif
 }
 
 /*************************************************************************
@@ -1245,17 +1149,11 @@ PaError PaHost_StreamActive( internalPortAudioStream   *past )
 /*************************************************************************/
 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->pahsc_AudioDeviceID, &timeStamp);
-  
-    streamTime = ( timeStamp.mFlags & kAudioTimeStampSampleTimeValid) ?
-            timeStamp.mSampleTime : past->past_FrameCount;
 
-    return streamTime;
+    // FIXME PaHost_UpdateStreamTime( pahsc );
+    return pahsc->pahsc_FramesPlayed;
 }
index 34fcee61dc3305064a9e4514c67aa6e43018940d..c631c9b3ce433401cee0afc11cae05fc729bf3dd 100644 (file)
@@ -1,6 +1,5 @@
-# Make PortAudio for Silicon Graphics IRIX 6.2 - 6.5.
-# Pieter suurmond, july 4, 2002. (for PA v18.)
-# Based on SGI-specific sproc()-method to spawn children, not on POSIX-threads.
+# Make PortAudio for Silicon Graphics IRIX (6.2)
+# Pieter suurmond, august 17, 2001. (v15 pa_sgi sub-version #0.04)
 
 # Instead of "-lpthread", as with linux,
 # just the audio- and math-library for SGI:
@@ -15,36 +14,36 @@ CFLAGS = -O2
 PASRC = ../pa_common/pa_lib.c pa_sgi.c
 PAINC = ../pa_common/portaudio.h
 
-# Tests that work (on SGI Indy with R5000 @ 180MHz running IRIX 6.2): 
-#TESTC = $(PASRC) ../pa_tests/patest_record.c    # TODO probably ok.
-#TESTC = $(PASRC) ../pa_tests/patest_many.c      # v18 ok (with PA_MIN_LATENCY_MSEC=250).
-#TESTC = $(PASRC) ../pa_tests/patest_latency.c   # v18 ok (with PA_MIN_LATENCY_MSEC=250) patest_latency.c contained //
-#TESTC = $(PASRC) ../pa_tests/patest_longsine.c  # v18 ok (with PA_MIN_LATENCY_MSEC=250).
-
-TESTC = $(PASRC) ../pa_tests/patest_saw.c       # v18 ok (with PA_MIN_LATENCY_MSEC=250).
-#TESTC = $(PASRC) ../pa_tests/patest_wire.c      # v18 seems ok.
-
-#TESTC = $(PASRC) ../pa_tests/pa_devs.c          # TODO probably ok.
-#TESTC = $(PASRC) ../pa_tests/patest_sine.c      # TODO probably ok.
-#TESTC = $(PASRC) ../pa_tests/patest_sine_time.c # TODO probably ok.
-#TESTC = $(PASRC) ../pa_tests/patest_sine8.c     # TODO probably ok.
-#TESTC = $(PASRC) ../pa_tests/patest_leftright.c # TODO probably ok.
-#TESTC = $(PASRC) ../pa_tests/patest_pink.c      # TODO probably ok.
-#TESTC = $(PASRC) ../pa_tests/patest_clip.c      # TODO probably ok.
-#TESTC = $(PASRC) ../pa_tests/patest_stop.c      # TODO probably ok.
-#TESTC = $(PASRC) ../pa_tests/patest_dither.c    # TODO probably ok.
-#TESTC = $(PASRC) ../pa_tests/patest_sync.c      # BEEPS and delta's, no crashes anymore with v15.
-
-# Tests that were not yet performed:
-#TESTC = $(PASRC) ../pa_tests/paqa_devs.c #  test??
-#TESTC = $(PASRC) ../pa_tests/paqa_errs.c #  test??
-#TESTC = $(PASRC) ../pa_tests/pa_fuzz.c   #  test??
-
+# Tests that work                                    (SGI Indy with R5000 @ 180MHz running IRIX 6.2). 
+#TESTC   = $(PASRC) ../pa_tests/patest_many.c      # OK
+TESTC   = $(PASRC) ../pa_tests/patest_record.c    # OK
+#TESTC   = $(PASRC) ../pa_tests/patest_latency.c   # OK
+#TESTC   = $(PASRC) ../pa_tests/patest_longsine.c  # OK but needs more than 4 buffers to do without glitches.
+#TESTC   = $(PASRC) ../pa_tests/patest_saw.c       # Seems OK (does it gracefully exit?).
+#TESTC   = $(PASRC) ../pa_tests/patest_wire.c      # OK
+#TESTC   = $(PASRC) ../pa_tests/pa_devs.c          # OK
+#TESTC   = $(PASRC) ../pa_tests/patest_sine.c      # OK
+#TESTC   = $(PASRC) ../pa_tests/patest_sine_time.c # OK
+#TESTC   = $(PASRC) ../pa_tests/patest_sine8.c     # OK
+#TESTC   = $(PASRC) ../pa_tests/patest_leftright.c # OK
+#TESTC   = $(PASRC) ../pa_tests/patest_pink.c      # OK
+#TESTC   = $(PASRC) ../pa_tests/patest_clip.c      # OK
+#TESTC   = $(PASRC) ../pa_tests/patest_stop.c      # OK
+#TESTC   = $(PASRC) ../pa_tests/patest_dither.c    # OK
+#TESTC   = $(PASRC) ../pa_tests/patest_sync.c      # BEEPS and delta's, no crashes anymore.
+
+# Tests that do not yet work.
+#TESTC   = $(PASRC) ../pa_tests/paqa_devs.c        # Heavy crash with core-dump after PaHost_OpenStream: opening 1 output channel(s) on AL default
+#TESTC   = $(PASRC) ../pa_tests/paqa_errs.c        # Heavy crash with core-dump after PaHost_OpenStream: opening 2 output channel(s) on AL default
+#TESTC   = $(PASRC) ../pa_tests/pa_fuzz.c    # THIS CRASHED MY WHOLE IRIX SYSTEM after "ENTER"! :-(
+                                             # PROCESS IN ITSELF RUNS OK, WITH LARGER BUFFSIZES THOUGH.
+                                             # OH MAYBE IT WAS BECAUSE DEBUGGING WAS ON???
+                                             # HMMM I'M NOT GONNA RUN THAT AGAIN... WAY TOO DANGEROUS!
 TESTH   = $(PAINC)
 
 all: patest
 
-# "cc" for the MIPSpro compiler, may be changed to "gcc":
+#(cc may be changed to gcc)
 patest: $(TESTC) $(TESTH) Makefile
        cc $(CFLAGS) $(TESTC) $(CDEFINES) $(LIBS) -o patest
 
index 0f562375169550bd3fd1e8f2aea1fc37d20e7a04..094cb4d831eb479e293782d6bbdb91ba35c953fc 100644 (file)
@@ -1,10 +1,10 @@
 /*
  * $Id$
- * PortAudio Portable Real-Time Audio Library. Copyright (c) 1999-2001 Phil Burk.
+ * PortAudio Portable Real-Time Audio Library
  * Latest Version at: http://www.portaudio.com
+ * SGI IRIX implementation by Pieter Suurmond, aug 17, 2001.
  *
- * Silicon Graphics (SGI) IRIX implementation by Pieter Suurmond.
- * This implementation uses sproc()-spawning, not the POSIX-threads.
+ * 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
  * 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.
- *
-MODIFICATIONS:
+ */
+/*
+Modfication History:
   8/12/2001 - Pieter Suurmond - took the v15 pa_linux_oss.c file and started to adapt for IRIX 6.2.
-  8/17/2001 - v15, first unstable alpha release for IRIX, sent to Phil & Ross. 
-  9/23/2001 - Many fixes and changes: POLLIN for input, not POLLOUT!
-  7/04/2002 - Implemented multiple user buffers per host buffer to allow clients that 
-              request smaller buffersizes.
-
- [v18-0.05] Try to use CVS via the Mac now to upload instead of e-mailing to Phil & Ross.
-
+  8/17/2001 - (v15 pa_sgi sub-version #0.04), wow, much is working now!  Send this to Phil & Ross. 
+              ID-stuff is nicer here now than in the linux_oss-alpha-version, v15. Was able to get 
+              rid of a number of globals (like "sNumDevices" for instance).
 TODO:
+  - Test under IRIX 6.5.
+  - Maybe use pthread instead of (platform-specific) poll/select/pollfd-calls. 
+    (As Gary Scavone more or less suggested(?)... But can I get enough process-control then?)
   - Dynamically switch to 32 bit float as native format when appropriate (let SGI do the conversion), 
     and maybe also the other natively supported formats? (might increase performance)
-  - Implement fancy callback block adapter as described in the PDF by Stephane Letz in the ASIO dir.
-  - Do some more tests... (see Makefile).
-
+  - Not sure whether CPU UTILIZATION MEASUREMENT (from OSS/linux) really works. Changed nothing yet,
+    seems ok, but I've not yet tested it thoroughly. (maybe utilization-code may be made _unix_common_ then?)
+  - Make sure that the fuzz-test doesn't let all IRIX crash (especially with higher buff-sizes).
+  - The minimal number of buffers setting... I do not yet fully understand it.. I now just take *4.
 REFERENCES:
   - IRIX 6.2 man pages regarding SGI AL library.
-  - IRIS Digital Media Programming Guide (online books and man-pages come
-    with IRIX 6.2 and may not be publically available on the internet).
+  - IRIS Digital MediaProgramming Guide (online books as well as man-pages come with IRIX 6.2 and 
+    may not be publically available on the internet).
 */
 
 #include <stdio.h>              /* Standard libraries. */
 #include <stdlib.h>
+#include <malloc.h>
+#include <memory.h>
+#include <math.h>
 
-#include "../pa_common/portaudio.h" /* (Makefile fails to find in subdirs, -I doesn't work?). */
-#include "../pa_common/pa_host.h"
-#include "../pa_common/pa_trace.h"
+#include "portaudio.h"          /* Portaudio headers. */
+#include "pa_host.h"
+#include "pa_trace.h"
 
-#include <sys/time.h>
+#include <sys/time.h>           /* System specific (IRIX 6.2). */
 #include <sys/types.h>
 #include <sys/prctl.h>
-#include <sys/schedctl.h>       /* For schedctl(NDPRI, NDPHIMIN). */
-#include <fcntl.h>              /* fcntl.h needed.                */
-#include <unistd.h>             /* For streams, ioctl(), etc.     */
+#include <sys/schedctl.h>
+#include <fcntl.h>              /* fcntl.h needed.             */
+#include <unistd.h>             /* For streams, ioctl(), etc.  */
+#include <signal.h>
 #include <ulocks.h>
 #include <poll.h>
-#include <dmedia/audio.h>      /* System specific (IRIX 6.2-6.5). */
-
-/*----------------- MACROS --------------------*/
-#define PRINT(x)    { printf x; fflush(stdout); }
-#define ERR_RPT(x)  PRINT(x)
-#define DBUG(x)     /* PRINT(x) */
-#define DBUGX(x)    /* PRINT(x) */
+#include <limits.h>
+#include <dmedia/audio.h>
 
-#define MAX_CHARS_DEVNAME           (16)
-#define MAX_SAMPLE_RATES            (8)         /* Known from SGI AL there are 7.                      */
-                                                /* Constants used in 'Pa_GetMinNumBuffers()' below:    */
-#define MIN_LATENCY_MSEC            (200)       /* Used if 'getenv("PA_MIN_LATENCY_MSEC")' fails.      */
-#define PA_LATENCY_ENV_NAME         ("PA_MIN_LATENCY_MSEC")        /* Same names as in file pa_unix.h. */
+/*--------------------------------------------*/
+#define PRINT(x)   { printf x; fflush(stdout); }
+#define ERR_RPT(x) PRINT(x)
+#define DBUG(x)    PRINT(x)
+#define DBUGX(x)   /* PRINT(x) */
 
-/*------------------------------- IRIX AL specific device info: --------------------------------------*/
-typedef struct                    internalPortAudioDevice
-{
-  PaDeviceID                      pad_DeviceID;                         /* THIS "ID" IS NEW HERE.         */
-  long                            pad_ALdevice;                         /* SGI-number!                    */
-  double                          pad_SampleRates[MAX_SAMPLE_RATES];    /* For pointing to from pad_Info  */
-  char                            pad_DeviceName[MAX_CHARS_DEVNAME+1];  /* +1 for \0, one more than OSS.  */
-  PaDeviceInfo                    pad_Info;                             /* pad_Info (v15) contains:       */
-  struct internalPortAudioDevice* pad_Next;                             /* Singly linked list (NULL=end). */
-} internalPortAudioDevice;
+#define MAX_CHARS_DEVNAME           (16)        /* Was 32 in OSS (20 for AL but "in"/"out" is concat. */
+#define MAX_SAMPLE_RATES            (8)         /* Known from SGI AL there are 7 (was 10 in OSS v15). */
 
-/*----------------- Structure containing all SGI IRIX specific data: ---------------------------------------*/
-typedef struct      PaHostSoundControl
+typedef struct                    internalPortAudioDevice                 /* IRIX specific device info:      */
 {
-  ALconfig          pahsc_ALconfigIN,                   /* IRIX-audio-library-datatype. Configuration       */
-                    pahsc_ALconfigOUT;                  /* stucts separate for input and output ports.      */
-  ALport            pahsc_ALportIN,                     /* IRIX-audio-library-datatype. ALports can only be */
-                    pahsc_ALportOUT;                    /* unidirectional, so we sometimes need 2 of them.  */
-  int               pahsc_threadPID;                    /* Sproc()-result, written by PaHost_StartEngine(). */
-
-  unsigned int      pahsc_UserBuffersPerHostBuffer,
-                    pahsc_SamplesPerInputHostBuffer,    /* Channels per frame are accounted for. */
-                    pahsc_SamplesPerOutputHostBuffer,
-                    pahsc_BytesPerInputHostBuffer,      /* Size per sample are accounted for. */
-                    pahsc_BytesPerOutputHostBuffer;
-  short            *pahsc_InputHostBuffer,              /* Allocated here, in this file, if necessary.      */
-                   *pahsc_OutputHostBuffer;
-
-  struct itimerval  pahsc_EntryTime,                    /* For measuring CPU utilization (same as linux).   */
-                    pahsc_LastExitTime;
-  long              pahsc_InsideCountSum,
-                    pahsc_TotalCountSum;
-} PaHostSoundControl;
+    PaDeviceID           /* NEW: */ pad_DeviceID;                           /* THIS "ID" IS NEW HERE (Pieter)! */
+    long                            pad_ALdevice;                           /* SGI-number!                     */
+    double                          pad_SampleRates[MAX_SAMPLE_RATES];      /* for pointing to from pad_Info   */
+    char                            pad_DeviceName[MAX_CHARS_DEVNAME+1];    /* +1 for \0, one more than OSS.   */
+    PaDeviceInfo                    pad_Info;                               /* pad_Info (v15) contains:        */
+    /* int            structVersion;                                           */
+    /* const char*    name;                                                    */
+    /* int            maxInputChannels, maxOutputChannels;                     */
+    /* int            numSampleRates;       Num rates, or -1 if range supprtd. */
+    /* const double*  sampleRates;          Array of supported sample rates,   */
+    /* PaSampleFormat nativeSampleFormats;  or {min,max} if range supported.   */
+    struct internalPortAudioDevice* pad_Next;                               /* Singly linked list, (NULL=end). */
+}
+internalPortAudioDevice;
 
-/*-------------------------------------------------------- Shared Data -------------------------------*/
-static internalPortAudioDevice* sDeviceList = NULL;     /* FIXME - put Mutex around this shared data. */
-static int                      sPaHostError = 0;       /* Maybe more than one process writing errs!? */
-usema_t                         *SendSema,              /* These variables are shared between the     */
-                                *RcvSema;               /* audio handling process and main process.   */
-/*--------------------------*/
-long Pa_GetHostError(void)
+typedef struct      PaHostSoundControl              /* Structure to contain all SGI IRIX specific data. */
 {
-    return (long)sPaHostError;
+    ALport            pahsc_ALportIN,                 /* IRIX-audio-library-datatype. ALports can only be */
+    pahsc_ALportOUT;                /* unidirectional, so we sometimes need 2 of them.  */
+    int               pahsc_threadPID;                /* Sproc()-result, written by PaHost_StartEngine(). */
+    short             *pahsc_NativeInputBuffer,       /* Allocated here, in this file, if necessary.      */
+    *pahsc_NativeOutputBuffer;
+    unsigned int      pahsc_BytesPerInputBuffer,      /* Native buffer sizes in bytes, really needed here */
+    pahsc_BytesPerOutputBuffer;     /* to free FAST memory, if buffs were alloctd FAST. */
+    unsigned int      pahsc_SamplesPerInputBuffer,    /* These amounts are needed again and again in the  */
+    pahsc_SamplesPerOutputBuffer;   /* audio-thread (don't need to be kept globally).   */
+    struct itimerval  pahsc_EntryTime,                /* For measuring CPU utilization (same as linux).   */
+                pahsc_LastExitTime;
+    long              pahsc_InsideCountSum,
+    pahsc_TotalCountSum;
 }
+PaHostSoundControl;
+
+/*----------------------------- Shared Data ------------------------------------------------------*/
+static internalPortAudioDevice* sDeviceList = NULL; /* FIXME - put Mutex around this shared data. */
+static int                      sPaHostError = 0;   /* Maybe more than one process writing errs!? */
 
 /*----------------------------- BEGIN CPU UTILIZATION MEASUREMENT -----------------*/
 /*                              (copied from source pa_linux_oss/pa_linux_oss.c)   */
@@ -131,7 +128,7 @@ static void Pa_StartUsageCalculation( internalPortAudioStream   *past )
     struct itimerval itimer;
     PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;
     if( pahsc == NULL ) return;
-/* Query system timer for usage analysis and to prevent overuse of CPU. */
+    /* Query system timer for usage analysis and to prevent overuse of CPU. */
     getitimer( ITIMER_REAL, &pahsc->pahsc_EntryTime );
 }
 
@@ -156,19 +153,19 @@ static void Pa_EndUsageCalculation( internalPortAudioStream   *past )
     if (pahsc == NULL)
         return;
     if (getitimer( ITIMER_REAL, &currentTime ) == 0 )
-        {
+    {
         if (past->past_IfLastExitValid)
-            {
+        {
             insideCount = SubtractTime_AminusB( &pahsc->pahsc_EntryTime, &currentTime );
             pahsc->pahsc_InsideCountSum += insideCount;
             totalCount =  SubtractTime_AminusB( &pahsc->pahsc_LastExitTime, &currentTime );
             pahsc->pahsc_TotalCountSum += totalCount;
-        /*  DBUG(("insideCount = %d, totalCount = %d\n", insideCount, totalCount )); */
+            /*  DBUG(("insideCount = %d, totalCount = %d\n", insideCount, totalCount )); */
             /* Low pass filter the result because sometimes we get called several times in a row. */
             /* That can cause the TotalCount to be very low which can cause the usage to appear   */
             /* unnaturally high. So we must filter numerator and denominator separately!!!        */
             if (pahsc->pahsc_InsideCountSum > 0)
-                {
+            {
                 past->past_AverageInsideCount = ((LOWPASS_COEFFICIENT_0 * past->past_AverageInsideCount) +
                                                  (LOWPASS_COEFFICIENT_1 * pahsc->pahsc_InsideCountSum));
                 past->past_AverageTotalCount  = ((LOWPASS_COEFFICIENT_0 * past->past_AverageTotalCount) +
@@ -176,10 +173,10 @@ static void Pa_EndUsageCalculation( internalPortAudioStream   *past )
                 past->past_Usage = past->past_AverageInsideCount / past->past_AverageTotalCount;
                 pahsc->pahsc_InsideCountSum = 0;
                 pahsc->pahsc_TotalCountSum = 0;
-                }
             }
-        past->past_IfLastExitValid = 1;
         }
+        past->past_IfLastExitValid = 1;
+    }
     pahsc->pahsc_LastExitTime.it_value.tv_sec = 100;
     pahsc->pahsc_LastExitTime.it_value.tv_usec = 0;
     setitimer( ITIMER_REAL, &pahsc->pahsc_LastExitTime, NULL );
@@ -192,56 +189,56 @@ PaError translateSGIerror(void) /* Calls oserror(), may be used after an SGI AL-
 {                               /* call to report via ERR_RPT(), yields a PaError-num.  */
     const char* a = "SGI AL ";  /* (Not absolutely sure errno came from THIS thread!    */
     switch(oserror())           /* Read IRIX man-pages about the _SGI_MP_SOURCE macro.) */
-        {
-        case AL_BAD_OUT_OF_MEM:
-             ERR_RPT(("%sout of memory.\n", a)); 
-             return paInsufficientMemory;                   /* Known PaError.   */
-        case AL_BAD_CONFIG:
-             ERR_RPT(("%sconfiguration invalid or NULL.\n", a));
-             return paHostError;                            /* Generic PaError. */
-        case AL_BAD_CHANNELS:
-             ERR_RPT(("%schannels not 1,2 or 4.\n", a));
-             return paHostError;                            /* Generic PaError. */
-        case AL_BAD_NO_PORTS:
-             ERR_RPT(("%sout of audio ports.\n", a));
-             return paHostError;                            /* Generic PaError. */
-        case AL_BAD_DEVICE:
-             ERR_RPT(("%swrong device number.\n", a));
-             return paHostError;                            /* Generic PaError. */
-        case AL_BAD_DEVICE_ACCESS:
-             ERR_RPT(("%swrong device access.\n", a));
-             return paHostError;                            /* Generic PaError. */
-        case AL_BAD_DIRECTION:
-             ERR_RPT(("%sinvalid direction.\n", a));
-             return paHostError;                            /* Generic PaError. */
-        case AL_BAD_SAMPFMT:
-             ERR_RPT(("%sdoesn't accept sampleformat.\n", a));
-             return paHostError;                            /* Generic PaError. */
-        case AL_BAD_FLOATMAX:
-             ERR_RPT(("%smax float value is zero.\n", a));
-             return paHostError;                            /* Generic PaError. */
-        case AL_BAD_WIDTH:
-             ERR_RPT(("%sunsupported samplewidth.\n", a));
-             return paHostError;                            /* Generic PaError. */
-        case AL_BAD_QSIZE:
-             ERR_RPT(("%sinvalid queue size.\n", a));
-             return paHostError;                            /* Generic PaError. */
-        case AL_BAD_PVBUFFER:
-             ERR_RPT(("%sPVbuffer null.\n", a));
-             return paHostError;                            /* Generic PaError. */
-        case AL_BAD_BUFFERLENGTH_NEG:
-             ERR_RPT(("%snegative bufferlength.\n", a));
-             return paHostError;                            /* Generic PaError. */
-        case AL_BAD_BUFFERLENGTH_ODD:
-             ERR_RPT(("%sodd bufferlength.\n", a));
-             return paHostError;                            /* Generic PaError. */
-        case AL_BAD_PARAM:
-             ERR_RPT(("%sparameter not valid for device.\n", a));
-             return paHostError;                            /* Generic PaError. */
-        default:
-             ERR_RPT(("%sunknown error.\n", a));
-             return paHostError;                            /* Generic PaError. */
-        }
+    {
+    case AL_BAD_OUT_OF_MEM:
+        ERR_RPT(("%sout of memory.\n", a));
+        return paInsufficientMemory;                   /* Known PaError.   */
+    case AL_BAD_CONFIG:
+        ERR_RPT(("%sconfiguration invalid or NULL.\n", a));
+        return paHostError;                            /* Generic PaError. */
+    case AL_BAD_CHANNELS:
+        ERR_RPT(("%schannels not 1,2 or 4.\n", a));
+        return paHostError;                            /* Generic PaError. */
+    case AL_BAD_NO_PORTS:
+        ERR_RPT(("%sout of audio ports.\n", a));
+        return paHostError;                            /* Generic PaError. */
+    case AL_BAD_DEVICE:
+        ERR_RPT(("%swrong device number.\n", a));
+        return paHostError;                            /* Generic PaError. */
+    case AL_BAD_DEVICE_ACCESS:
+        ERR_RPT(("%swrong device access.\n", a));
+        return paHostError;                            /* Generic PaError. */
+    case AL_BAD_DIRECTION:
+        ERR_RPT(("%sinvalid direction.\n", a));
+        return paHostError;                            /* Generic PaError. */
+    case AL_BAD_SAMPFMT:
+        ERR_RPT(("%sdoesn't accept sampleformat.\n", a));
+        return paHostError;                            /* Generic PaError. */
+    case AL_BAD_FLOATMAX:
+        ERR_RPT(("%smax float value is zero.\n", a));
+        return paHostError;                            /* Generic PaError. */
+    case AL_BAD_WIDTH:
+        ERR_RPT(("%sunsupported samplewidth.\n", a));
+        return paHostError;                            /* Generic PaError. */
+    case AL_BAD_QSIZE:
+        ERR_RPT(("%sinvalid queue size.\n", a));
+        return paHostError;                            /* Generic PaError. */
+    case AL_BAD_PVBUFFER:
+        ERR_RPT(("%sPVbuffer null.\n", a));
+        return paHostError;                            /* Generic PaError. */
+    case AL_BAD_BUFFERLENGTH_NEG:
+        ERR_RPT(("%snegative bufferlength.\n", a));
+        return paHostError;                            /* Generic PaError. */
+    case AL_BAD_BUFFERLENGTH_ODD:
+        ERR_RPT(("%sodd bufferlength.\n", a));
+        return paHostError;                            /* Generic PaError. */
+    case AL_BAD_PARAM:
+        ERR_RPT(("%sparameter not valid for device.\n", a));
+        return paHostError;                            /* Generic PaError. */
+    default:
+        ERR_RPT(("%sunknown error.\n", a));
+        return paHostError;                            /* Generic PaError. */
+    }
 }
 
 /*------------------------------------------------------------------------------------------*/
@@ -258,15 +255,15 @@ static PaError Pa_sgiQueryDevice(long                     ALdev,  /* (AL_DEFAULT
     pad->pad_ALdevice = ALdev;                              /* Set the AL device number.    */
     pad->pad_DeviceID = id;                                 /* Set the PA device number.    */
     if (strlen(name) > MAX_CHARS_DEVNAME)                   /* MAX_CHARS defined above.     */
-        {
+    {
         ERR_RPT(("Pa_QueryDevice(): name too long (%s).\n", name));
         return paHostError;
-        }
+    }
     strcpy(pad->pad_DeviceName, name);                      /* Write name-string.           */
     pad->pad_Info.name = pad->pad_DeviceName;               /* Set pointer,..hmmm.          */
     /*--------------------------------- natively supported sample formats: -----------------*/
     pad->pad_Info.nativeSampleFormats = paInt16; /* Later also include paFloat32 | ..| etc. */
-                                                 /* Then also choose other CallConvertXX()! */
+    /* Then also choose other CallConvertXX()! */
     /*--------------------------------- number of available i/o channels: ------------------*/
     if (ALgetminmax(ALdev, AL_INPUT_COUNT, &min, &max))
         return translateSGIerror();
@@ -276,8 +273,8 @@ static PaError Pa_sgiQueryDevice(long                     ALdev,  /* (AL_DEFAULT
         return translateSGIerror();
     pad->pad_Info.maxOutputChannels = max;
     DBUG(("Pa_QueryDevice: maxOutputChannels = %d\n", pad->pad_Info.maxOutputChannels))
-    /*--------------------------------- supported samplerates: ----------------------*/ 
-    pad->pad_Info.numSampleRates = 7;   
+    /*--------------------------------- supported samplerates: ----------------------*/
+    pad->pad_Info.numSampleRates = 7;
     pad->pad_Info.sampleRates = pad->pad_SampleRates;
     pad->pad_SampleRates[0] = (double)AL_RATE_8000;     /* long -> double. */
     pad->pad_SampleRates[1] = (double)AL_RATE_11025;
@@ -293,18 +290,18 @@ static PaError Pa_sgiQueryDevice(long                     ALdev,  /* (AL_DEFAULT
     if (ALgetminmax(ALdev, AL_OUTPUT_RATE, &min, &max)) /* Ask OUTPUT rate-max.      */
         return translateSGIerror();
     if (max != (long)(0.5 + pad->pad_SampleRates[6]))
-        {
+    {
 weird:  ERR_RPT(("Pa_sgiQueryDevice() did not confirm max samplerate (%ld)\n",max));
         return paHostError;             /* Or make it a warning and just carry on... */
-        }
-    /*-------------------------------------------------------------------------------*/ 
+    }
+    /*-------------------------------------------------------------------------------*/
     return paNoError;
 }
 
 
 /*--------------------------------------------------------------------------------*/
 int Pa_CountDevices()       /* Name of this function suggests it only counts and  */
-{                           /* is NOT destructive, it however resets whole PA !   */   
+{                           /* is NOT destructive, it however resets whole PA !   */
     int                        numDevices = 0;        /* Let 's not do that here. */
     internalPortAudioDevice*   currentDevice = sDeviceList;   /* COPY GLOBAL VAR. */
 #if 0                       /* Remains from linux_oss v15: Pa_Initialize(), on    */
@@ -312,13 +309,15 @@ int Pa_CountDevices()       /* Name of this function suggests it only counts and
         Pa_Initialize();    /* Isn't that a bit too 'rude'?        Don't be too   */
 #endif                      /* friendly to clients that forgot to initialize PA.  */
     while (currentDevice)   /* Slower but more elegant than the sNumDevices-way:  */
-        {
+    {
         numDevices++;
         currentDevice = currentDevice->pad_Next;
-        }
+    }
     return numDevices;
 }
 
+
+
 /*-------------------------------------------------------------------------------*/
 static internalPortAudioDevice *Pa_GetInternalDevice(PaDeviceID id)
 {
@@ -326,21 +325,22 @@ static internalPortAudioDevice *Pa_GetInternalDevice(PaDeviceID id)
     internalPortAudioDevice     *res = (internalPortAudioDevice*)NULL;
     internalPortAudioDevice     *pad = sDeviceList;         /* COPY GLOBAL VAR.  */
     while (pad)                         /* pad may be NULL, that's ok, return 0. */
-        {  /* (Added ->pad_DeviceID field to the pad-struct, Pieter, 2001.)      */
+    {  /* (Added ->pad_DeviceID field to the pad-struct, Pieter, 2001.)      */
         if (pad->pad_DeviceID == id)    /* This the device we were looking for?  */
             res = pad;                  /* But keep on(!) counting so we don't   */
         numDevices++;                   /* have to call Pa_CountDevices() later. */
         pad = pad->pad_Next;            /* Advance to the next device or NULL.   */
-        }                               /* No assumptions about order of ID's in */
+    }                               /* No assumptions about order of ID's in */
     if (!res)                           /* the list.                             */
         ERR_RPT(("Pa_GetInternalDevice() could not find specified ID (%d).\n",id));
     if ((id < 0) || (id >= numDevices))
-        {
+    {
         ERR_RPT(("Pa_GetInternalDevice() supplied with an illegal ID (%d).\n",id));
 #if 1                                             /* Be strict, even when found, */
         res = (internalPortAudioDevice*)NULL;     /* do not accept illegal ID's. */
 #endif
-        }
+
+    }
     return res;
 }
 
@@ -359,7 +359,7 @@ const PaDeviceInfo* Pa_GetDeviceInfo(PaDeviceID id)
 /*------------------------------------------------*/
 PaDeviceID Pa_GetDefaultInputDeviceID(void)
 {
-    return 0;   /* 0 is the default device ID. */
+    return 0; /* 0 is the default device ID. */
 }
 /*------------------------------------------------*/
 PaDeviceID Pa_GetDefaultOutputDeviceID(void)
@@ -367,26 +367,26 @@ PaDeviceID Pa_GetDefaultOutputDeviceID(void)
     return 0;
 }
 
-/*-------------------------------------------------------------------------------------------------*/
-/* Build linked a list with all the available audio devices on this SGI machine (only 1 for now).  */
-PaError PaHost_Init(void)                              /* Called by Pa_Initialize() from pa_lib.c. */
+/*--------------------------------------------------------------------------------------*/
+/* Build linked list with all available audio devices on this SGI machine.              */
+PaError PaHost_Init(void)                   /* Called by Pa_Initialize() from pa_lib.c. */
 {
     internalPortAudioDevice*    pad;
     PaError                     r = paNoError;
-    int                         audioLibFileID;             /* To test for the presence of audio.  */
+    int                         audioLibFileID;
 
-    if (sDeviceList)                                        /* Allow re-init, only warn, no error. */
-        {
+    if (sDeviceList)            /* Allow re-init, only warn, no err.  */
+    {
         ERR_RPT(("Warning: PaHost_Init() did not really re-init PA.\n"));
         return r;
-        }
-    /*------------- ADD THE SGI DEFAULT DEVICE TO THE LIST: ---------------------------------------*/
+    }
+    /*------------- ADD THE SGI DEFAULT DEVICES TO THE LIST: --------------------------------------*/
     audioLibFileID = open("/dev/hdsp/hdsp0master", O_RDONLY);   /* Try to open Indigo style audio  */
     if (audioLibFileID < 0)                                     /* IO port. On failure, machine    */
-        {                                                       /* has no audio ability.           */
+    {                                                       /* has no audio ability.           */
         ERR_RPT(("PaHost_Init(): This machine has no (Indigo-style) audio abilities.\n"));
         return paHostError;
-        }
+    }
     close(audioLibFileID);                              /* Allocate fast mem to hold device info.  */
     pad = PaHost_AllocateFastMemory(sizeof(internalPortAudioDevice));
     if (pad == NULL)
@@ -397,17 +397,21 @@ PaError PaHost_Init(void)                              /* Called by Pa_Initializ
                           "AL default",                 /* A suitable name.                        */
                           pad);                         /* Write args and queried info into pad.   */
     if (r != paNoError)
-        {
+    {
         ERR_RPT(("Pa_QueryDevice for '%s' returned: %d\n", pad->pad_DeviceName, r));
         PaHost_FreeFastMemory(pad, sizeof(internalPortAudioDevice));   /* sDeviceList still NULL ! */
-        }
+    }
     else
-        sDeviceList = pad;            /* First element in linked list. pad->pad_Next already NULL. */
-    /*------------- QUERY AND ADD MORE POSSIBLE SGI DEVICES TO THE LINKED LIST: -------------------*/
-    /*---------------------------------------------------------------------------------------------*/
+        sDeviceList = pad;      /* First element in linked list (pad->pad_Next is already NULL).   */
+    /*------------- QUERY AND ADD MORE POSSIBLE SGI DEVICES TO THE LIST: --------------*/
+    /*---------------------------------------------------------------------------------*/
     return r;
 }
 
+/*------------------------------------------------------------------*/
+usema_t *SendSema,  /* These variables are shared between the audio */
+*RcvSema;   /* handling process and the main process.       */
+
 /*--------------------------------------------------------------------------------------------*/
 #define MIN(a,b)    ((a)<(b)?(a):(b))   /* MIN()-function is used below.                      */
 #define kPollSEMA   0                   /* To index the pollfd-array, reads nicer than just   */
@@ -415,169 +419,114 @@ PaError PaHost_Init(void)                              /* Called by Pa_Initializ
 #define kPollIN     2
 void Pa_SgiAudioProcess(void *v)        /* This function is sproc-ed by PaHost_StartEngine()  */
 {                                       /* as a separate thread. (Argument must be void*).    */
-    short                   evtLoop;    /* Reset by parent indirectly, or at local errors.    */
+    short                   evtLoop=1;  /* Reset by parent indirectly, or at local errors.    */
     PaError                 result;
     struct pollfd           PollFD[3];  /* To catch kPollSEMA-, kPollOUT- and kPollIN-events. */
-    internalPortAudioStream *past  = (internalPortAudioStream*)v;  /* Copy void-ptr-argument. */
-    PaHostSoundControl      *pahsc;
-    short                   n, inputEvent, outputEvent, semaEvent;    /* .revents are shorts. */
-    short                   *inBuffer, *outBuffer; /* FIX: Only 16 bit for now, may change... */               
-    unsigned int            samplesPerInputUserBuffer, samplesPerOutputUserBuffer;
-
-    DBUG(("Entering sproc-thread.\n"));
-    if (!past)
-        {
-        sPaHostError = paInternalError;                 /* Or paBadStreamPtr ? */
-        ERR_RPT(("argument NULL!\n"));
-        goto skip;
-        }
-    pahsc = (PaHostSoundControl*)past->past_DeviceData;
-    if (!pahsc)
-        {
+    internalPortAudioStream *past  = (internalPortAudioStream*)v;   /* Copy void-ptr-argument.*/
+    PaHostSoundControl      *pahsc = (PaHostSoundControl*)past->past_DeviceData;
+    if (pahsc == NULL)
+    {
         sPaHostError = paInternalError; /* The only way is to signal error to shared area?!   */
-        ERR_RPT(("past_DeviceData NULL!\n"));
-        goto skip;                      /* Sproc-ed threads MAY NOT RETURN paInternalError.   */
-        }
-    /*----------------------------- open AL-ports here, after sproc(): -----------------------*/
-    if (past->past_NumInputChannels > 0)                                  /* Open input port. */
-        {       
-        pahsc->pahsc_ALportIN = ALopenport("PA sgi in", "r", pahsc->pahsc_ALconfigIN);
-        if (!pahsc->pahsc_ALportIN)
-            {
-            ERR_RPT(("Failed to open AL input port.\n"));
-            sPaHostError = paInternalError;
-            goto skip;
-            }
-        DBUG(("Opened %d input channel(s).\n", past->past_NumInputChannels));
-        samplesPerInputUserBuffer = pahsc->pahsc_SamplesPerInputHostBuffer /
-                                    pahsc->pahsc_UserBuffersPerHostBuffer;
-        }
-     if (past->past_NumOutputChannels > 0)                               /* Open output port. */
-        {       
-        pahsc->pahsc_ALportOUT = ALopenport("PA sgi out", "w", pahsc->pahsc_ALconfigOUT);
-        if (!pahsc->pahsc_ALportOUT)
-            {
-            ERR_RPT(("Failed to open AL output port.\n"));
-            sPaHostError = paInternalError;                 /* Assume pahsc_ALconfigs are the */
-            goto skip;                                      /* same for IN and OUT in case    */
-            }                                               /* both ports are opened (bidir). */
-        DBUG(("Opened %d output channel(s).\n", past->past_NumOutputChannels));
-        samplesPerOutputUserBuffer = pahsc->pahsc_SamplesPerOutputHostBuffer /
-                                     pahsc->pahsc_UserBuffersPerHostBuffer;
-        DBUG(("samplesPerOutputUserBuffer = %d\n", samplesPerOutputUserBuffer));
-        }    
-    /*-----------------------------------------------------------------------*/
+        goto skipALL;                   /* Sproc-ed threads MAY NOT RETURN paInternalError.   */
+    }
     past->past_IsActive = 1;            /* Wasn't this already done by the calling parent?!   */
+    DBUG(("entering thread.\n"));
     PollFD[kPollIN].fd = ALgetfd(pahsc->pahsc_ALportIN);    /* ALgetfd returns -1 on failures */
-    PollFD[kPollIN].events = POLLIN;                        /* such as ALport not there.      */
+    PollFD[kPollIN].events = POLLOUT;                       /* such as ALport not there.      */
+    /* .events = POLLOUT ??? ok? */
     PollFD[kPollOUT].fd = ALgetfd(pahsc->pahsc_ALportOUT);
     PollFD[kPollOUT].events = POLLOUT;                      /* .events = POLLOUT is OK.       */
     schedctl(NDPRI, NDPHIMIN);              /* Sets non-degrading priority for this process.  */
     PollFD[kPollSEMA].fd = usopenpollsema(SendSema, 0777);  /* To communicate with parent.    */
     PollFD[kPollSEMA].events = POLLIN;                      /* .events = POLLIN is OK.        */
-    uspsema(SendSema);              /* Blocks until ... MUST be here, this uspsema(). */
-    evtLoop = ((past->past_StopNow | past->past_StopSoon) == 0);
-    while (evtLoop)
-        {
+    uspsema(SendSema);              /* Blocks until the next (first)signal is received???? */
+    do
+    {
         /*---------------------------- SET FILLPOINTS AND WAIT UNTIL SOMETHING HAPPENS: ----------*/
-        if (pahsc->pahsc_InputHostBuffer)         /* Then pahsc_ALportIN should also be there!  */
+        if (pahsc->pahsc_NativeInputBuffer)         /* Then pahsc_ALportIN should also be there!  */
             /* For input port, fill point is number of locations in the sample queue that must be */
             /* filled in order to trigger a return from select(). (or poll())                     */
             /* Notice IRIX docs mention number of samples as argument, not number of sampleframes.*/
-            if (ALsetfillpoint(pahsc->pahsc_ALportIN, pahsc->pahsc_SamplesPerInputHostBuffer))
-                {                                    /* Multiple amount as transferred per time.  */
+            if (ALsetfillpoint(pahsc->pahsc_ALportIN, pahsc->pahsc_SamplesPerInputBuffer))
+            {                                       /* Same amount as transferred per time.   */
                 ERR_RPT(("ALsetfillpoint() for ALportIN failed.\n"));
                 sPaHostError = paInternalError;         /* (Using exit(-1) would be a bit rude.)  */
-                goto skip;
-                }
-        if (pahsc->pahsc_OutputHostBuffer)        /* Then pahsc_ALportOUT should also be there! */
+                goto skipIO;
+            }
+        if (pahsc->pahsc_NativeOutputBuffer)        /* Then pahsc_ALportOUT should also be there! */
             /* For output port, fill point is number of locations that must be free in order to   */
             /* wake up from select(). (or poll())                                                 */
-            if (ALsetfillpoint(pahsc->pahsc_ALportOUT, pahsc->pahsc_SamplesPerOutputHostBuffer))
-                {
+            if (ALsetfillpoint(pahsc->pahsc_ALportOUT, pahsc->pahsc_SamplesPerOutputBuffer))
+            {
                 ERR_RPT(("ALsetfillpoint() for ALportOUT failed.\n"));
                 sPaHostError = paInternalError;         /* (Using exit(-1) would be a bit rude.)  */
-                goto skip;
-                }                   /* poll() with timeout=-1 makes it block until a requested    */
+                goto skipIO;
+            }                   /* poll() with timeout=-1 makes it block until a requested    */
         poll(PollFD, 3, -1);        /* event occurs or until call is interrupted. If fd-value in  */
-                                    /* array <0, events is ignored and revents is set to 0.       */
+        /* array <0, events is ignored and revents is set to 0.       */
         /*---------------------------- MESSAGE-EVENT FROM PARENT THREAD: -------------------------*/
-        semaEvent = PollFD[kPollSEMA].revents & POLLIN;
-        if (semaEvent)
-            {
-            if (past->past_StopSoon)
+        if (PollFD[kPollSEMA].revents & POLLIN)
+        {
+            if (past->past_StopNow || past->past_StopSoon)
                 evtLoop = 0;
+            uspsema(SendSema);  /* Decrements count of previously allocated semaphore SendSema. If count  */
+            /* is then negative, semaphore will logically block calling process until */
+            /* count is incremented due to an usvsema call made by another process.   */
+            usvsema(RcvSema);   /* Increments the count associated with RcvSema. If there are any         */
+            /* processes queued waiting for the semaphore the first one is awakened.  */
+            /* Here usvsema sends an acknowledgement to the "SendAudioCommand()".     */
             if (past->past_StopNow)
-                goto skip;
-            }
-        /*------------------------------------- FILLED-EVENT FROM INPUT BUFFER: --------------------------*/
-        inputEvent = PollFD[kPollIN].revents & POLLIN;
-        if (inputEvent)         /* Don't need to check (pahsc->pahsc_InputHostBuffer):  */
-            {                   /* if buffer was not there, ALport not there, no events!  */
-            if (ALreadsamps(pahsc->pahsc_ALportIN, (void*)pahsc->pahsc_InputHostBuffer,
-                            pahsc->pahsc_SamplesPerInputHostBuffer))
-                {                           /* Here again: number of samples instead of number of frames. */
+                goto skipIO;    /* Else go on for a little while... */
+        }
+        /*------------------------------------- FREE-EVENT FROM INPUT BUFFER: ----------------------------*/
+        if (PollFD[kPollIN].revents & POLLOUT)  /* Don't need to check (pahsc->pahsc_NativeInputBuffer):  */
+        {                                   /* if buffer was not there, ALport not there, no events!  */
+            if (ALreadsamps(pahsc->pahsc_ALportIN, (void*)pahsc->pahsc_NativeInputBuffer,
+                            pahsc->pahsc_SamplesPerInputBuffer))
+            {                           /* Here again: number of samples instead of number of frames. */
                 ERR_RPT(("ALreadsamps() failed.\n"));
                 sPaHostError = paInternalError;
-                goto skip;
-                }
+                goto skipIO;                    /* (Using exit(-1) would be a bit rude.) */
             }
-        outputEvent = PollFD[kPollOUT].revents & POLLOUT;
+        }
         /*------------------------------------- USER-CALLBACK-ROUTINE: -----------------------------------*/
-        if (inputEvent | outputEvent)           /* (Bitwise is ok.) */
-            { /* To be sure we that really DID input-transfer or gonna DO output-transfer, and that it is */
-              /* not just "sema"- (i.e. user)-event, or some other system-event that awakened the poll(). */
+        if ((PollFD[kPollIN].revents & POLLOUT) || (PollFD[kPollOUT].revents & POLLOUT))
+        { /* To be sure we that really DID input-transfer or gonna DO output-transfer, and that it is */
+            /* not just "sema"- (i.e. user)-event, or some other system-event that awakened the poll(). */
             Pa_StartUsageCalculation(past);                         /* Convert 16 bit native data to      */
-                                                                    /* user data and call user routine.   */
-            inBuffer  = pahsc->pahsc_InputHostBuffer;               /* Short pointers for now, care! */
-            outBuffer = pahsc->pahsc_OutputHostBuffer;
-            n = pahsc->pahsc_UserBuffersPerHostBuffer;              /* 'n' may never start at NULL ! */
-            do  {
-                result = Pa_CallConvertInt16(past, inBuffer, outBuffer);
-                if (result)    /* This is apparently NOT an error! Just letting the userCallBack stop us. */
-                    { DBUG(("Pa_CallConvertInt16() returned %d, stopping...\n", result)); goto skip; }
-                inBuffer  += samplesPerInputUserBuffer;             /* Num channels is accounted for. */
-                outBuffer += samplesPerOutputUserBuffer;
-                } while (--n);
+            result = Pa_CallConvertInt16(past,                      /* user data and call user routine.   */
+                                         pahsc->pahsc_NativeInputBuffer,
+                                         pahsc->pahsc_NativeOutputBuffer);
             Pa_EndUsageCalculation(past);
-            }                 
-        /*------------------------------------- FREE-EVENT FROM OUTPUT BUFFER: ---------------------------*/
-        if (outputEvent)        /* Don't need to check (pahsc->pahsc_OutputHostBuffer)  */
-            {                   /* because if filedescriptor not there, no event for it.  */
-            if (ALwritesamps(pahsc->pahsc_ALportOUT, (void*)pahsc->pahsc_OutputHostBuffer,
-                             pahsc->pahsc_SamplesPerOutputHostBuffer))
-                {
-                ERR_RPT(("ALwritesamps() failed.\n"));  /* Better use SEMAS for messaging back to parent! */
-                sPaHostError = paInternalError;
-                goto skip;
-                }
+            if (result)
+            {
+                DBUG(("Pa_CallConvertInt16() returned %d, stopping...\n", result));
+                goto skipIO;                    /* But it is apparently NOT an error!     */
+            }                               /* Just letting the userCallBack stop us. */
+        }
+        /*------------------------------------- FILLED-EVENT FROM OUTPUT BUFFER: -------------------------*/
+        if (PollFD[kPollOUT].revents & POLLOUT) /* Don't need to check (pahsc->pahsc_NativeOutputBuffer)  */
+        {                                   /* because if filedescriptor not there, no event for it.  */
+            if (ALwritesamps(pahsc->pahsc_ALportOUT, (void*)pahsc->pahsc_NativeOutputBuffer,
+                             pahsc->pahsc_SamplesPerOutputBuffer))
+            {
+                ERR_RPT(("ALwritesamps() failed.\n"));
+                sPaHostError = paInternalError;    /* Better use SEMAS also for messaging back to parent! */
+                goto skipIO;
             }
         }
-skip:
-    /*------------------------------- close AL-ports ----------------------------*/
-    if (pahsc->pahsc_ALportIN)
-        {
-        if (ALcloseport(pahsc->pahsc_ALportIN))
-            translateSGIerror();   /* Translates SGI AL-code to PA-code and ERR_RPTs string. */
-        else                                /* But go on anyway... to release other stuff... */
-            pahsc->pahsc_ALportIN = (ALport)0;
-        }
-    if (pahsc->pahsc_ALportOUT)
-        {
-        if (ALcloseport(pahsc->pahsc_ALportOUT))
-            translateSGIerror();
-        else
-            pahsc->pahsc_ALportOUT = (ALport)0;
-        }
+        /*------------------------------------------------------------------------------------------------*/
+    }
+    while (evtLoop);                      /* Set at init-time, only reset indirectly via semaphore, */
+skipIO:                                         /* or in case of error, only within this loop.            */
+    DBUG(("leaving thread.\n"));             /* Don't we need to cleanup semaphore-stuff / thread itself? */
+skipALL:                                     /* (make threadPID in the struct -1 again, for instance?)    */
     past->past_IsActive = 0;
-    if (semaEvent)
-        {
-        uspsema(SendSema);  /* StopEngine() was still waiting for this acknowledgement. */
-        usvsema(RcvSema);   /* (semaEvent initialized with 0.)          */
-        }
-    DBUG(("Leaving sproc-thread.\n"));
-}
-
+    pahsc->pahsc_threadPID == -1;           /* Signal back, so StopEngine() for example won't call KILL().... hmmm doesn't work yet!  */
+    /* SHIT: when this process ends, it also KILLS of the parent!!! because sigint = kill?? */
+    exit(0);            /* Unix process. SIGCLD is sent to parent (if prctl wa called with 0 by parent). */
+}                       /* if prctl was called with 9 by parent, then when this process ends, it also    */
+/* KILLS off the parent!!!                                                       */
 
 /*--------------------------------------------------------------------------------------*/
 PaError PaHost_OpenStream(internalPortAudioStream *past)
@@ -586,167 +535,190 @@ PaError PaHost_OpenStream(internalPortAudioStream *past)
     PaHostSoundControl      *pahsc;
     unsigned int            minNumBuffers;
     internalPortAudioDevice *padIN, *padOUT;        /* For looking up native AL-numbers. */
-    long                    pvbuf[8], sr, alq;      /* To get/set hardware configs.      */
-
+    ALconfig                sgiALconfig = NULL;     /* IRIX-datatype.   */
+    long                    pvbuf[8];               /* To get/set hardware configs.      */
+    long                    sr, ALqsize;
     DBUG(("PaHost_OpenStream() called.\n"));        /* Alloc FASTMEM and init host data. */
     if (!past)
-        {
+    {
         ERR_RPT(("Streampointer NULL!\n"));
-        result = paBadStreamPtr; goto done;
-        }
+        result = paBadStreamPtr;        goto done;
+    }
     pahsc = (PaHostSoundControl*)PaHost_AllocateFastMemory(sizeof(PaHostSoundControl));
     if (pahsc == NULL)
+    {
+        ERR_RPT(("FAST Memory allocation failed.\n"));  /* Pass trough some ERR_RPT-exit-  */
+        result = paInsufficientMemory;  goto done;      /* code (nothing will be freed).   */
+    }
+    memset(pahsc, 0, sizeof(PaHostSoundControl));   /* Hmmm, not too elegant, besides, the */
+    pahsc->pahsc_threadPID = -1;                    /* pahsc_threadPID must be inited to   */
+    past->past_DeviceData = (void*)pahsc;           /* -1 instead of 0! ??                 */
+    /*--------------------------------------------------- Allocate native buffers: --------*/
+    pahsc->pahsc_SamplesPerInputBuffer = past->past_FramesPerUserBuffer * /* Needed by the */
+                                         past->past_NumInputChannels;     /* audio-thread. */
+    pahsc->pahsc_BytesPerInputBuffer   = pahsc->pahsc_SamplesPerInputBuffer * sizeof(short);
+    if (past->past_NumInputChannels > 0)                       /* Assumes short = 16 bits! */
+    {
+        pahsc->pahsc_NativeInputBuffer = (short *) malloc(pahsc->pahsc_BytesPerInputBuffer);
+        if( pahsc->pahsc_NativeInputBuffer == NULL )
         {
-        ERR_RPT(("FAST Memory allocation failed.\n"));  /* Pass trough some ERR_RPT-exit- */
-        result = paInsufficientMemory; goto done;       /* code (nothing will be freed).  */
+            ERR_RPT(("(normal yet) Memory allocation failed.\n"));
+            result = paInsufficientMemory;
+            goto done;
+        }
+    }
+    pahsc->pahsc_SamplesPerOutputBuffer = past->past_FramesPerUserBuffer * /* Needed by the */
+                                          past->past_NumOutputChannels;    /* audio-thread. */
+    pahsc->pahsc_BytesPerOutputBuffer   = pahsc->pahsc_SamplesPerOutputBuffer * sizeof(short);
+    if (past->past_NumOutputChannels > 0)                       /* Assumes short = 16 bits! */
+    {
+        pahsc->pahsc_NativeOutputBuffer = (short *) malloc(pahsc->pahsc_BytesPerOutputBuffer);
+        if (pahsc->pahsc_NativeOutputBuffer == NULL)
+        {
+            ERR_RPT(("(normal yet) Memory allocation failed.\n"));
+            result = paInsufficientMemory;  goto done;
         }
-    memset(pahsc, 0, sizeof(PaHostSoundControl));
-    pahsc->pahsc_threadPID = -1;                    /* Should pahsc_threadPID be inited to */
-    past->past_DeviceData = (void*)pahsc;           /* -1 instead of 0 ??                  */
+    }
     /*------------------------------------------ Manipulate hardware if necessary and allowed: --*/
     ALseterrorhandler(0);                           /* 0 = turn off the default error handler.   */
     pvbuf[0] = AL_INPUT_RATE;
     pvbuf[2] = AL_INPUT_COUNT;
     pvbuf[4] = AL_OUTPUT_RATE;              /* TO FIX: rates may be logically, not always in Hz! */
     pvbuf[6] = AL_OUTPUT_COUNT;
-    sr = (long)(past->past_SampleRate + 0.5);   /* Common for both input and output :-) */
-    /*-----------------------------------------------------------------------------*/
-    /* OVERWRITE 'past_NumUserBuffers'-field in the struct supplied by the caller. */
-    /* This field may be set to zero by a client application to ask for minimum    */
-    /* latency. It is used below, to set both input- and output-AL-queuesizes.     */    
-    minNumBuffers = Pa_GetMinNumBuffers(past->past_FramesPerUserBuffer,
-                                        past->past_SampleRate);   /* Take biggest. */   
-    past->past_NumUserBuffers = (minNumBuffers > past->past_NumUserBuffers) ? 
-                                 minNumBuffers : past->past_NumUserBuffers;
-    DBUG(("past->past_NumUserBuffers=%d\n", past->past_NumUserBuffers));
-    /*----------------------------------------------------------------------------------*/
-    pahsc->pahsc_UserBuffersPerHostBuffer = past->past_NumUserBuffers >> 1;
-    DBUG(("pahsc_UserBuffersPerHostBuffer=%d\n",pahsc->pahsc_UserBuffersPerHostBuffer));
-    /*  1 is minimum because Pa_GetMinNumBuffers() returns >= 2.
-        Callback will be called 'pahsc_UserBuffersPerHostBuffer' times (with 'past_FramesPerUserBuffer')
-        per host transfer. */
-    /*---------------------------------------------------- SET INPUT CONFIGURATION: ---------------------*/
-    if (past->past_NumInputChannels > 0)                                /* We need to lookup the corre-  */
-        {                                                               /* sponding native AL-number(s). */
-        /*--------------------------------------------------- Allocate native buffers: --------------*/
-        pahsc->pahsc_SamplesPerInputHostBuffer = pahsc->pahsc_UserBuffersPerHostBuffer *
-                                                 past->past_FramesPerUserBuffer *       /* Needed by the */
-                                                 past->past_NumInputChannels;           /* audio-thread. */
-        DBUG(("pahsc_SamplesPerInputHostBuffer=%d\n", pahsc->pahsc_SamplesPerInputHostBuffer));
-        pahsc->pahsc_BytesPerInputHostBuffer = pahsc->pahsc_SamplesPerInputHostBuffer * sizeof(short);      
-        pahsc->pahsc_InputHostBuffer = (short*)PaHost_AllocateFastMemory(pahsc->pahsc_BytesPerInputHostBuffer);        
-        if (!pahsc->pahsc_InputHostBuffer)
-            {
-            ERR_RPT(("Fast memory allocation failed (in).\n"));
-            result = paInsufficientMemory; 
-            goto done;
-            }
+    sr = (long)(past->past_SampleRate + 0.5);   /* Common for input and output :-)               */
+    if (past->past_NumInputChannels > 0)                        /* We need to lookup the corre-  */
+    {                                                       /* sponding native AL-number(s). */
         padIN = Pa_GetInternalDevice(past->past_InputDeviceID);
         if (!padIN)
-            {
+        {
             ERR_RPT(("Pa_GetInternalDevice() for input failed.\n"));
-            result = paHostError;
-            goto done;
-            }
+            result = paHostError;  goto done;
+        }
         if (ALgetparams(padIN->pad_ALdevice, &pvbuf[0], 4)) /* Although input and output will both be on */
             goto sgiError;                                  /* the same AL-device, the AL-library might  */
         if (pvbuf[1] != sr)                                 /* contain more than AL_DEFAULT_DEVICE in    */
-            {  /* Rate different from current harware-rate?    the future. Therefore 2 seperate queries. */
+        {  /* Rate different from current harware-rate?    the future. Therefore 2 seperate queries. */
             if (pvbuf[3] > 0)     /* Means, there's other clients using AL-input-ports */
-                {
+            {
                 ERR_RPT(("Sorry, not allowed to switch input-hardware to %ld Hz because \
-another process is currently using input at %ld Hz.\n", sr, pvbuf[1]));
-                result = paHostError;
-                goto done;
-                }
+                         another process is currently using input at %ld kHz.\n", sr, pvbuf[1]));
+                result = paHostError;   goto done;
+            }
             pvbuf[1] = sr;                  /* Then set input-rate. */
             if (ALsetparams(padIN->pad_ALdevice, &pvbuf[0], 2))
-                goto sgiError;        /* WHETHER THIS SAMPLERATE WAS REALLY PRESENT IN OUR ARRAY OF RATES, */
-            }                         /* IS NOT CHECKED, AT LEAST NOT BY ME, WITHIN THIS FILE! Does PA do? */
-        pahsc->pahsc_ALconfigIN = ALnewconfig();                       /* Released at PaHost_CloseStream().  */
-        if (pahsc->pahsc_ALconfigIN == (ALconfig)0)
-            goto sgiError;
-        if (ALsetsampfmt(pahsc->pahsc_ALconfigIN, AL_SAMPFMT_TWOSCOMP))/* Choose paInt16 as native i/o-format.      */
-            goto sgiError;
-        if (ALsetwidth (pahsc->pahsc_ALconfigIN, AL_SAMPLE_16))        /* Only meaningful when sample format for    */
-            goto sgiError;                                      /* config is set to two's complement format. */
-        /************************ Future versions might (dynamically) switch to 32-bit floats? *******
-        if (ALsetsampfmt(pahsc_ALconfigIN, AL_SAMPFMT_FLOAT))    (Then also call another CallConvert-func.)
-            goto sgiError;
-        if (ALsetfloatmax (pahsc_ALconfigIN, 1.0))       Only meaningful when sample format for config 
-            goto sgiError;                               is set to AL_SAMPFMT_FLOAT or AL_SAMPFMT_DOUBLE. */
-        /*--------- Set internal AL queuesize (in samples, not in frames!) -------------------------------*/
-        alq = (long)past->past_NumUserBuffers * past->past_FramesPerUserBuffer * past->past_NumInputChannels;
-        DBUG(("AL input queuesize = %ld samples.\n", alq));
-        if (ALsetqueuesize(pahsc->pahsc_ALconfigIN, alq))
-            goto sgiError;
-        if (ALsetchannels (pahsc->pahsc_ALconfigIN, (long)(past->past_NumInputChannels)))
-            goto sgiError;                              /* Returns 0 on success, -1 on failure. */
+                goto sgiError;  /* WHETHER THIS SAMPLERATE WAS REALLY PRESENT IN OUR ARRAY OF RATES,    */
         }
-    /*---------------------------------------------------- SET OUTPUT CONFIGURATION: ------------------------*/
-    if (past->past_NumOutputChannels > 0)               /* CARE: padOUT/IN may NOT be NULL if Channels <= 0! */
-        {                                               /* We use padOUT/IN later on, or at least 1 of both. */     
-        pahsc->pahsc_SamplesPerOutputHostBuffer = pahsc->pahsc_UserBuffersPerHostBuffer *
-                                                  past->past_FramesPerUserBuffer *          /* Needed by the */
-                                                  past->past_NumOutputChannels;             /* audio-thread. */
-        DBUG(("pahsc_SamplesPerOutputHostBuffer=%d\n", pahsc->pahsc_SamplesPerOutputHostBuffer));
-        pahsc->pahsc_BytesPerOutputHostBuffer   = pahsc->pahsc_SamplesPerOutputHostBuffer * sizeof(short);
-        pahsc->pahsc_OutputHostBuffer = (short*)PaHost_AllocateFastMemory(pahsc->pahsc_BytesPerOutputHostBuffer);
-        if (!pahsc->pahsc_OutputHostBuffer)
-            {
-            ERR_RPT(("Fast memory allocation failed (out).\n"));
-            result = paInsufficientMemory;
-            goto done;
-            }
+    }
+    if (past->past_NumOutputChannels > 0)           /* CARE: padOUT/IN may NOT be NULL if Channels<=0!   */
+    {                                           /* We use padOUT/IN later on, or at least 1 of both. */
         padOUT = Pa_GetInternalDevice(past->past_OutputDeviceID);
         if (!padOUT)
-            {
+        {
             ERR_RPT(("Pa_GetInternalDevice() for output failed.\n"));
-            result = paHostError;
-            goto done;
-            }
+            result = paHostError;  goto done;
+        }
         if (ALgetparams(padOUT->pad_ALdevice,&pvbuf[4], 4))
             goto sgiError;
-        if (pvbuf[5] != sr)
-            {   /* Output needed and rate different from current harware-rate. */
+        if ((past->past_NumOutputChannels > 0) && (pvbuf[5] != sr))
+        {   /* Output needed and rate different from current harware-rate. */
             if (pvbuf[7] > 0)     /* Means, there's other clients using AL-output-ports */
-                {
+            {
                 ERR_RPT(("Sorry, not allowed to switch output-hardware to %ld Hz because \
-another process is currently using output at %ld Hz.\n", sr, pvbuf[5]));            
-                result = paHostError;
-                goto done;                              /* Will free again the inputbuffer */
-                }                                       /* that was just created above.    */
+                         another process is currently using output at %ld kHz.\n", sr, pvbuf[5]));
+                result = paHostError;   goto done;      /* Will free again the inputbuffer */
+            }                                       /* that was just created above.    */
             pvbuf[5] = sr;                  /* Then set output-rate. */
             if (ALsetparams(padOUT->pad_ALdevice, &pvbuf[4], 2))
                 goto sgiError;
-            }
-        pahsc->pahsc_ALconfigOUT = ALnewconfig();                           /* Released at PaHost_CloseStream(). */
-        if (pahsc->pahsc_ALconfigOUT == (ALconfig)0)
-            goto sgiError;
-        if (ALsetsampfmt(pahsc->pahsc_ALconfigOUT, AL_SAMPFMT_TWOSCOMP))    /* Choose paInt16 as native i/o-format. */
-            goto sgiError;
-        if (ALsetwidth (pahsc->pahsc_ALconfigOUT, AL_SAMPLE_16))        /* Only meaningful when sample format for    */
-            goto sgiError;                                              /* config is set to two's complement format. */
-                                                /** Future versions might (dynamically) switch to 32-bit floats. **/
-        alq = (long)past->past_NumUserBuffers * past->past_FramesPerUserBuffer * past->past_NumOutputChannels;
-        DBUG(("AL output queuesize = %ld samples.\n", alq));
-        if (ALsetqueuesize(pahsc->pahsc_ALconfigOUT, alq))
-            goto sgiError;
-        if (ALsetchannels (pahsc->pahsc_ALconfigOUT, (long)(past->past_NumOutputChannels)))
-            goto sgiError;
         }
-    /*----------------------------------------------- TEST DEVICE ID's: --------------------*/
-    if ((past->past_OutputDeviceID != past->past_InputDeviceID) &&          /* Who SETS these devive-numbers? */
-        (past->past_NumOutputChannels > 0) && (past->past_NumInputChannels > 0))
-        { 
-        ERR_RPT(("Cannot setup bidirectional stream between different devices.\n"));
-        result = paHostError;
-        goto done;
+    }
+    /*------------------------------------------ Construct an audio-port-configuration ----------*/
+    sgiALconfig = ALnewconfig();                    /* Change the SGI-AL-default-settings.       */
+    if (sgiALconfig == (ALconfig)0)                 /* sgiALconfig is released here after use!   */
+        goto sgiError;                              /* See that sgiALconfig is NOT released!     */
+    if (ALsetsampfmt(sgiALconfig, AL_SAMPFMT_TWOSCOMP))  /* Choose paInt16 as native i/o-format. */
+        goto sgiError;
+    if (ALsetwidth (sgiALconfig, AL_SAMPLE_16))     /* Only meaningful when sample format for    */
+        goto sgiError;                              /* config is set to two's complement format. */
+    /************************ Future versions might (dynamically) switch to 32-bit floats? *******
+    if (ALsetsampfmt(sgiALconfig, AL_SAMPFMT_FLOAT))    (Then also call another CallConvert-func.)
+        goto sgiError;
+    if (ALsetfloatmax (sgiALconfig, 1.0))       Only meaningful when sample format for config 
+        goto sgiError;                          is set to AL_SAMPFMT_FLOAT or AL_SAMPFMT_DOUBLE. */
+    /*---------- ?? --------------------*/
+    /* 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;
+    /*------------------------------------------------ Set internal AL queuesize (in samples) ----*/
+    if (pahsc->pahsc_SamplesPerInputBuffer >= pahsc->pahsc_SamplesPerOutputBuffer)
+        ALqsize = (long)pahsc->pahsc_SamplesPerInputBuffer;
+    else                                            /* Take the largest of the two amounts.       */
+        ALqsize = (long)pahsc->pahsc_SamplesPerOutputBuffer;
+    ALqsize *= 4;                                   /* 4 times as large as amount per transfer!   */
+    if (ALsetqueuesize(sgiALconfig, ALqsize))       /* Or should we use past_NumUserBuffers here? */
+        goto sgiError;                              /* Using 2 times may give glitches... */
+    /* Have to work on ALsetqueuesize() above, fillpoints in the thread are ok now. */
+
+    /* Do ALsetchannels() later, apart per input and/or output. */
+    /*----------------------------------------------- OPEN 1 OR 2 AL-DEVICES: --------------------*/
+    if (past->past_OutputDeviceID == past->past_InputDeviceID)  /* Who SETS these devive-numbers? */
+    {
+        if ((past->past_NumOutputChannels > 0) && (past->past_NumInputChannels > 0))
+        {
+            DBUG(("PaHost_OpenStream: opening both input and output channels.\n"));
+            /*------------------------- open output port: ----------------------------------*/
+            if (ALsetchannels (sgiALconfig, (long)(past->past_NumOutputChannels)))
+                goto sgiError;                      /* Returns 0 on success, -1 on failure. */
+            pahsc->pahsc_ALportOUT = ALopenport("PA sgi out", "w", sgiALconfig);
+            if (pahsc->pahsc_ALportOUT == (ALport)0)
+                goto sgiError;
+            /*------------------------- open input port: -----------------------------------*/
+            if (ALsetchannels (sgiALconfig, (long)(past->past_NumInputChannels)))
+                goto sgiError;                      /* Returns 0 on success, -1 on failure. */
+            pahsc->pahsc_ALportIN = ALopenport("PA sgi in", "r", sgiALconfig);
+            if (pahsc->pahsc_ALportIN == (ALport)0)
+                goto sgiError;          /* For some reason the "patest_wire.c"-test crashes! */
+        }                           /* Probably due to too small buffersizes?....        */
+        else
+        {
+            ERR_RPT(("Cannot setup bidirectional stream between different devices.\n"));
+            result = paHostError;
+            goto done;
+        }
+    }
+    else /* (OutputDeviceID != InputDeviceID) */
+    {
+        if (past->past_NumOutputChannels > 0)   /* WRITE-ONLY: */
+        {
+            /*------------------------- open output port: ----------------------------------*/
+            DBUG(("PaHost_OpenStream: opening %d output channel(s) on %s.\n",
+                  past->past_NumOutputChannels, padOUT->pad_DeviceName));
+            if (ALsetchannels (sgiALconfig, (long)(past->past_NumOutputChannels)))
+                goto sgiError;                      /* Returns 0 on success, -1 on failure. */
+            pahsc->pahsc_ALportOUT = ALopenport("PA sgi out", "w", sgiALconfig);
+            if (pahsc->pahsc_ALportOUT == (ALport)0)
+                goto sgiError;
+        }
+        if (past->past_NumInputChannels > 0)   /* READ-ONLY: */
+        {
+            /*------------------------- open input port: -----------------------------------*/
+            DBUG(("PaHost_OpenStream: opening %d input channel(s) on %s.\n",
+                  past->past_NumInputChannels, padIN->pad_DeviceName));
+            if (ALsetchannels (sgiALconfig, (long)(past->past_NumInputChannels)))
+                goto sgiError;                      /* Returns 0 on success, -1 on failure. */
+            pahsc->pahsc_ALportIN = ALopenport("PA sgi in", "r", sgiALconfig);
+            if (pahsc->pahsc_ALportIN == (ALport)0)
+                goto sgiError;
         }
+    }
+    DBUG(("PaHost_OpenStream() succeeded.\n"));
     goto done;  /* (no errors occured) */
-sgiError:   
+sgiError:
     result = translateSGIerror();   /* Translates SGI AL-code to PA-code and ERR_RPTs string. */
 done:
+    if (sgiALconfig)
+        ALfreeconfig(sgiALconfig);              /* We don't need that struct anymore. */
     if (result != paNoError)
         PaHost_CloseStream(past);               /* Frees memory (only if really allocated!).  */
     return result;
@@ -768,54 +740,56 @@ PaError PaHost_StartEngine(internalPortAudioStream *past)
     PaHostSoundControl  *pahsc;
     usptr_t             *arena;
     if (!past)          /* Test argument. */
-        {
+    {
         ERR_RPT(("PaHost_StartEngine(NULL)!\n"));
         return paBadStreamPtr;
-        }
+    }
     pahsc = (PaHostSoundControl*)past->past_DeviceData;
     if (!pahsc)
-        {
+    {
         ERR_RPT(("PaHost_StartEngine(arg): arg->past_DeviceData = NULL!\n"));
         return paHostError;
-        }
+    }
     past->past_StopSoon = 0;            /* Assume SGI ALport is already opened! */
     past->past_StopNow  = 0;            /* Why don't we check pahsc for NULL?   */
     past->past_IsActive = 1;
-    
+
     /* Although the pthread_create() function, as well as <pthread.h>, may be   */
     /* available in IRIX, use sproc() on SGI to create audio-background-thread. */
     /* (Linux/oss uses pthread_create() instead of __clone() because:           */
     /*  - pthread_create also works for other UNIX systems like Solaris,        */
     /*  - Java HotSpot VM crashes in pthread_setcanceltype() using __clone().)  */
-    
+
     usconfig(CONF_ARENATYPE, US_SHAREDONLY);    /* (From SGI-AL-examples, file  */
     arena = usinit(tmpnam(0));                  /*  motifexample.c, function    */
     SendSema = usnewpollsema(arena, 0);         /*  InitializeAudioProcess().)  */
-    RcvSema = usnewsema(arena, 1);              /* 1= common mutual exclusion semaphore, where 1 and only 1 process
-                                                   will be permitted through a semaphore at a time.  Values > 1
-                                                   imply that up to val resources may be simultaneously used, but requests
-                                                   for more than val resources cause the calling process to block until a
-                                                   resource comes free (by a process holding a resource performing a
-                                                   usvsema().                IS THIS usnewsema() TOO PLATFORM SPECIFIC? */
-    prctl(PR_SETEXITSIG, 0);                    /* No not (void*)9, but 0, which doesn't kill the parent! */
-                                                /* PR_SETEXITSIG controls whether all members of a share group will be
-                                                   signaled if any one of them leaves the share group (either via exit()
-                                                   or exec()).  If 2nd arg, interpreted as an int is 0, then normal IRIX
-                                                   process termination rules apply, namely that the parent is sent a 
-                                                   SIGCLD upon death of child, but no indication of death of parent is 
-                                                   given.  If the second argument is a valid signal number then if any 
-                                                   member of a share group leaves the share group, a signal is
-                                                   sent to ALL surviving members of the share group.  */
+    RcvSema = usnewsema(arena, 1); /* 1= common mutual exclusion semaphore, where 1 and only 1 process
+                                                              will be permitted through a semaphore at a time.  Values > 1
+                                                              imply that up to val resources may be simultaneously used, but requests
+                                                              for more than val resources cause the calling process to block until a
+                                                              resource comes free (by a process holding a resource performing a
+                                                              usvsema().                  IS THIS usnewsema() TOO PLATFORM SPECIFIC? */
+    prctl(PR_SETEXITSIG, 0);/* No not (void*)9, but 0, which doesn't kill the parent! */
+    /* PR_SETEXITSIG controls whether all members of a share group will be
+                     signaled if any one of them leaves the share group
+                     (either via exit() or exec()).  If second
+                     argument, interpreted as an int is 0, then normal IRIX
+                     process termination rules apply, namely that the parent
+                     is sent a SIGCLD upon death of child, but no indication
+                     of death of parent is given.  If the second argument is
+                     a valid signal number then if any member
+                     of a share group leaves the share group, a signal is
+                     sent to ALL surviving members of the share group.  */
     /* SPAWN AUDIO-CHILD: */
     pahsc->pahsc_threadPID = sproc(Pa_SgiAudioProcess, /* Returns process ID of */
                                    PR_SALL,            /* new process, or -1.   */
-                                   (void*)past);       /* Pass past as optional */  /* IS THIS SAFE, will past never */
-    if (pahsc->pahsc_threadPID == -1)                  /* third void-ptr-arg.   */  /* be moved around in memory???? */
-        {
+                                   (void*)past);       /* Pass past as optional */
+    if (pahsc->pahsc_threadPID == -1)                  /* third void-ptr-arg.   */
+    {
         ERR_RPT(("PaHost_StartEngine() failed to spawn audio-thread.\n"));
         sPaHostError = oserror();   /* Pass native error-number to shared area. */
         return paHostError;         /* But return the generic error-number.     */
-        }
+    }
     return paNoError;               /* Hmmm, errno may come from other threads in same group! */
 }                                   /* ("man sproc" in IRIX6.2 to read about _SGI_MP_SOURCE.) */
 
@@ -825,45 +799,34 @@ PaError PaHost_StopEngine(internalPortAudioStream *past, int abort)
     int                 hres;
     long                timeOut;
     PaError             result = paNoError;
-    PaHostSoundControl  *pahsc;
-    
-    DBUG(("PaHost_StopEngine() called.\n"));
-    if (!past)
-        return paBadStreamPtr;
-    pahsc = (PaHostSoundControl*)past->past_DeviceData;
-                                                    /* Prevent from doing this twice!! */
-    if ((!pahsc) ||                                 /* Some tests call this CLOSE twice!! */
-        (!past->past_IsActive) || 
-        past->past_StopSoon || past->past_StopNow)
-        return result;              /* paNoError (already stopped, no err?).       */
+    PaHostSoundControl  *pahsc = (PaHostSoundControl*)past->past_DeviceData;
+
+    if (pahsc == NULL)
+        return result;              /* paNoError */
     past->past_StopSoon = 1;        /* Tell background thread to stop generating   */
     if (abort)                      /* more and to let current data play out. If   */
         past->past_StopNow = 1;     /* aborting, tell backgrnd thread to stop NOW! */
-                                    /*---- USE SEMAPHORE LOCK TO COMMUNICATE: -----*/
+
+    /*---- USE SEMAPHORE LOCK TO COMMUNICATE: -----*/
     usvsema(SendSema);              /* Increments count associated with SendSema.  */
-                                    /* Wait for the response.                      */
+    /* Wait for the response.                      */
     uspsema(RcvSema);               /* Decrements count of previously allocated    */
-                                    /* semaphore specified by RcvSema.             */
-    while (past->past_IsActive)     /* REALLY WAIT. */
-        {
-        /* DBUG(("wait 1 ms for audio-thread to stop.\n")); */
-        Pa_Sleep(1);
-        }
-
-#if 0   /* We don't need to KILL(), just COMMUNICATE and be patient...             */
+    /* semaphore specified by RcvSema.             */
+    /* Must be sure sub-process is really there,... otherwise above semas block?!  */
     if (pahsc->pahsc_threadPID != -1)   /* Did we really init it to -1 somewhere?  */
-        {
-        DBUG(("PaHost_StopEngine() is about to kill(SIGKILL) audio-thread.\n"));
+    {
+        /* How to JOIN a "sproc"-thread to recover memory resources????? */
+        /* hres = pthread_join( pahsc->pahsc_ThreadPID, NULL );          */
+        DBUG(("PaHost_StopEngine() is about to KILL(SIGKILL) audio-thread.\n"));
         if (kill(pahsc->pahsc_threadPID, SIGKILL))  /* Or SIGTERM or SIGQUIT(core)  */
-            {                                       /* Returns -1 in case of error. */
+        {                                       /* Returns -1 in case of error. */
             result = paHostError;
             sPaHostError = oserror();   /* Hmmm, other threads may also write here! */
             ERR_RPT(("PaHost_StopEngine() failed to kill audio-thread.\n"));
-            }
+        }
         else
             pahsc->pahsc_threadPID = -1;    /* Notify that we've killed this thread. */
-        }
-#endif
+    }
     past->past_IsActive = 0;    /* Even when kill() failed and pahsc_threadPID still there??? */
     return result;
 }
@@ -883,106 +846,76 @@ PaError PaHost_CloseStream(internalPortAudioStream *past)
 {
     PaHostSoundControl  *pahsc;
     PaError             result = paNoError;
-    
-    DBUG(("PaHost_CloseStream() called.\n"));
-    if (!past)
+
+    if (past == NULL)
         return paBadStreamPtr;
     pahsc = (PaHostSoundControl *) past->past_DeviceData;
-    if (!pahsc)             /* If pahsc not NULL, past_DeviceData will be freed, and set to NULL. */
-        return result;      /* This test prevents from freeing NULL-pointers. */
+    if (pahsc == NULL)          /* If pahsc not NULL, past_DeviceData will be freed, and set to NULL. */
+        return result;          /* This test prevents from freeing NULL-pointers. */
 
-    if (pahsc->pahsc_ALconfigIN)
-        {                                   /* Release configuration structs, only if allocated. */
-        ALfreeconfig(pahsc->pahsc_ALconfigIN);
-        pahsc->pahsc_ALconfigIN = NULL;
-        }
-    if (pahsc->pahsc_ALconfigOUT)
-        {
-        ALfreeconfig(pahsc->pahsc_ALconfigOUT); /* (Al-ports were already closed by audioProcess). */
-        pahsc->pahsc_ALconfigOUT = NULL;
-        }
-    if (pahsc->pahsc_InputHostBuffer)
-        {
-        PaHost_FreeFastMemory(pahsc->pahsc_InputHostBuffer, pahsc->pahsc_BytesPerInputHostBuffer);        
-        pahsc->pahsc_InputHostBuffer = NULL;
-        }
-    if (pahsc->pahsc_OutputHostBuffer)
-        {
-        PaHost_FreeFastMemory(pahsc->pahsc_OutputHostBuffer, pahsc->pahsc_BytesPerOutputHostBuffer);
-        pahsc->pahsc_OutputHostBuffer = NULL;
-        }
-    PaHost_FreeFastMemory(pahsc, sizeof(PaHostSoundControl));
-    past->past_DeviceData = NULL;    /* PaHost_OpenStream() allocated FAST MEM. */
+    if (pahsc->pahsc_ALportIN)
+    {
+        if (ALcloseport(pahsc->pahsc_ALportIN))
+            result = translateSGIerror();   /* Translates SGI AL-code to PA-code and ERR_RPTs string. */
+        else                                /* But go on anyway... to release other stuff... */
+            pahsc->pahsc_ALportIN = (ALport)0;
+    }
+    if (pahsc->pahsc_ALportOUT)
+    {
+        if (ALcloseport(pahsc->pahsc_ALportOUT))
+            result = translateSGIerror();
+        else
+            pahsc->pahsc_ALportOUT = (ALport)0;
+    }
+    if (pahsc->pahsc_NativeInputBuffer)
+    {
+        free(pahsc->pahsc_NativeInputBuffer);
+        pahsc->pahsc_NativeInputBuffer = NULL;
+    }
+    if (pahsc->pahsc_NativeOutputBuffer)
+    {
+        free(pahsc->pahsc_NativeOutputBuffer);
+        pahsc->pahsc_NativeOutputBuffer = NULL;
+    }
+    PaHost_FreeFastMemory(pahsc, sizeof(PaHostSoundControl));   /* Not just free(pahsc) because */
+    past->past_DeviceData = NULL;   /* PaHost_OpenStream(); allocated FAST (thus mpinned?) MEM. */
     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 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.
+*/
+#define PA_LATENCY_ENV_NAME  ("PA_MIN_LATENCY_MSEC")
 
-/*------------------------------------------------------------------------*/
-/* Determine minimum number of buffers required for (SGI) host based on   */
-/* minimum latency. Latency can be optionally set by user by setting an   */
-/* environment variable. For example, to set my latency to 200 msec, I've */
-/* put this line in my '.cshrc' file:    setenv PA_MIN_LATENCY_MSEC 200   */
-/* It always calls the 'PRINT' macro.                                     */
-/* The minimum number that is returned is 2.                              */
-/* This number is directly proportional to the AL-queue sizes to set up.  */
-/* It is one more than the number of user buffers per host buffer - in    */
-/* case minimum is returned, or, twice the user buffers per host buffer.  */
-/*------------------------------------------------------------------------*/
-int Pa_GetMinNumBuffers(int framesPerUserBuffer, double framesPerSecond)
+int Pa_GetMinNumBuffers( int framesPerBuffer, double sampleRate )
 {
-    int     minBuffers, minLatencyMsec;
-    char    *minLatencyText;
-    double  actualLatency;
-    
-    minLatencyText = getenv(PA_LATENCY_ENV_NAME); /* Defined at top of file. */
-    if (minLatencyText)
-        {
-        minLatencyMsec = atoi(minLatencyText);
-        if (minLatencyMsec < 10)
-            {             /* 10 is the minimum. */
-            minLatencyMsec = 10;
-            PRINT (("Environment variable 'PA_MIN_LATENCY_MSEC' below minimum of %d milliseconds.\n",
-                minLatencyMsec));
-            }
-        else if (minLatencyMsec > 4000)
-            {             /* 4000 is the maximum. */
-            minLatencyMsec = 4000;
-            PRINT (("Environment variable 'PA_MIN_LATENCY_MSEC' above maximum of %d milliseconds.\n",
-                minLatencyMsec));
-            }
-        else
-            PRINT (("Using environment variable 'PA_MIN_LATENCY_MSEC' (set to %d milliseconds).\n",
-                minLatencyMsec));
-        }
-    else
-        {
-        minLatencyMsec = MIN_LATENCY_MSEC;   /* Defined at top of this file. */
-        PRINT (("Environment variable 'PA_MIN_LATENCY_MSEC' not found.\nUsing default of %d milliseconds\n",
-            minLatencyMsec));
-        }
-    minBuffers = (int)((minLatencyMsec * framesPerSecond) /
-                       (1000.0 * framesPerUserBuffer));
-    if (minBuffers < 2)
-        minBuffers = 2;
-    actualLatency = 1000.0 * minBuffers * framesPerUserBuffer / framesPerSecond;
-    PRINT (("Actual AL latency set to %.2f milliseconds\n", actualLatency));
-    return minBuffers;
+    return 2;
 }
+/* Hmmm, the note above isn't appropriate for SGI I'm afraid... */
+/* Do we HAVE to do it this way under IRIX???....               */
+/*--------------------------------------------------------------*/
+
 
 /*---------------------------------------------------------------------*/
-PaError PaHost_Term(void)   /* Frees all of the linked audio-devices.  */
+PaError PaHost_Term(void)   /* Frees all of the linked devices.        */
 {                           /* Called by Pa_Terminate() from pa_lib.c. */
     internalPortAudioDevice *pad = sDeviceList,
-                            *nxt;
+                                   *nxt;
     while (pad)
-        {
+    {
         DBUG(("PaHost_Term: freeing %s\n", pad->pad_DeviceName));
         nxt = pad->pad_Next;
         PaHost_FreeFastMemory(pad, sizeof(internalPortAudioDevice));
         pad = nxt;              /* PaHost_Init allocated this FAST MEM.*/
-        }
+    }
     sDeviceList = (internalPortAudioDevice*)NULL;
-    return 0;                           /* Got rid of   sNumDevices=0; */
+    return 0;                           /* Got rid of sNumDevices=0; */
 }
 
 /***********************************************************************/
@@ -1007,17 +940,17 @@ void *PaHost_AllocateFastMemory(long numBytes)
 {
     void *addr = malloc(numBytes);  /* mpin() reads into memory all pages over the given */
     if (addr)                       /* range and locks the pages into memory. A counter  */
-        {                           /* is incremented each time the page is locked. The  */
+    {                           /* is incremented each time the page is locked. The  */
         if (mpin(addr, numBytes))   /* superuser can lock as many pages as it wishes,    */
-            {                       /* others are limited to the configurable PLOCK_MA.  */
+        {                       /* others are limited to the configurable PLOCK_MA.  */
             ERR_RPT(("PaHost_AllocateFastMemory() failed to mpin() memory.\n"));
 #if 1
             free(addr);             /* You MAY cut out these 2 lines to be less strict,  */
             addr = NULL;            /* you then only get the warning but PA goes on...   */
 #endif                              /* Only problem then may be corresponding munpin()   */
-            }                       /* call at PaHost_FreeFastMemory(), below.           */
+        }                       /* call at PaHost_FreeFastMemory(), below.           */
         memset(addr, 0, numBytes);  /* Locks established with mlock are not inherited by */
-        }                           /* a child process after a fork. Furthermore, IRIX-  */
+    }                           /* a child process after a fork. Furthermore, IRIX-  */
     return addr;                    /* man-pages warn against mixing both mpin and mlock */
 }                                   /* in 1 piece of code, so stick to mpin()/munpin() ! */
 
@@ -1028,11 +961,11 @@ void *PaHost_AllocateFastMemory(long numBytes)
 void PaHost_FreeFastMemory(void *addr, long numBytes)
 {
     if (addr)
-        {
+    {
         if (munpin(addr, numBytes))     /* Will munpin() fail when it was never mpinned? */
             ERR_RPT(("WARNING: PaHost_FreeFastMemory() failed to munpin() memory.\n"));
         free(addr);                     /* But go on, try to release it, just warn...    */
-        }
+    }
 }
 
 /*----------------------------------------------------------*/
@@ -1050,9 +983,9 @@ PaError PaHost_StreamActive( internalPortAudioStream   *past )
 /*-------------------------------------------------------------------*/
 PaTimestamp Pa_StreamTime( PortAudioStream *stream )
 {
-    internalPortAudioStream *past = (internalPortAudioStream *) stream; 
-/* FIXME - return actual frames played, not frames generated.
-** Need to query the output device somehow.
-*/
+    internalPortAudioStream *past = (internalPortAudioStream *) stream;
+    /* FIXME - return actual frames played, not frames generated.
+    ** Need to query the output device somehow.
+    */
     return past->past_FrameCount;
 }
diff --git a/pa_sgi/pthread-Makefile b/pa_sgi/pthread-Makefile
deleted file mode 100644 (file)
index 527677a..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-# Make PortAudio for Silicon Graphics IRIX (6.2)
-# Pieter suurmond, september 22, 2001. (v15 pa_sgi sub-version #0.18)
-
-# pthread, math (as with linux) and SGI audio library:
-# SGI-books say -lpthread should be the last on the line.
-LIBS = -lm -laudio -lpthread
-
-CDEFINES = -I../pa_common
-
-# Possible CFLAGS with MIPSpro compiler are: -32, -o32, -n32, -64,
-# -mips1, -mips2, -mips3, -mips4, etc. Use -g, -g2, -g3 for debugging. 
-# And use for example -O2 or -O3 for better optimization:
-CFLAGS = -O2
-PASRC = ../pa_common/pa_lib.c pa_sgi.c
-PAINC = ../pa_common/portaudio.h
-
-# Tests that work                                  (SGI Indy with R5000 @ 180MHz running IRIX 6.2). 
-#TESTC = $(PASRC) ../pa_tests/patest_record.c    # OK
-#TESTC = $(PASRC) ../pa_tests/patest_many.c      # OK
-#TESTC = $(PASRC) ../pa_tests/patest_latency.c   # OK
-#TESTC = $(PASRC) ../pa_tests/patest_longsine.c  # OK but needs more than 4 buffers to do without glitches.
-TESTC = $(PASRC) ../pa_tests/patest_saw.c       # Seems OK (does it gracefully exit?).
-#TESTC = $(PASRC) ../pa_tests/patest_wire.c      # OK
-#TESTC = $(PASRC) ../pa_tests/pa_devs.c          # OK
-#TESTC = $(PASRC) ../pa_tests/patest_sine.c      # OK
-#TESTC = $(PASRC) ../pa_tests/patest_sine_time.c # OK
-#TESTC = $(PASRC) ../pa_tests/patest_sine8.c     # OK
-#TESTC = $(PASRC) ../pa_tests/patest_leftright.c # OK
-#TESTC = $(PASRC) ../pa_tests/patest_pink.c      # OK
-#TESTC = $(PASRC) ../pa_tests/patest_clip.c      # OK
-#TESTC = $(PASRC) ../pa_tests/patest_stop.c      # OK
-#TESTC = $(PASRC) ../pa_tests/patest_dither.c    # OK
-#TESTC = $(PASRC) ../pa_tests/patest_sync.c      # BEEPS and delta's, no crashes anymore.
-
-# Tests that do not yet work.
-#TESTC = $(PASRC) ../pa_tests/paqa_devs.c # Heavy crash with core-dump after PaHost_OpenStream: opening 1 output channel(s) on AL default
-#TESTC = $(PASRC) ../pa_tests/paqa_errs.c # Heavy crash with core-dump after PaHost_OpenStream: opening 2 output channel(s) on AL default
-#TESTC = $(PASRC) ../pa_tests/pa_fuzz.c   # THIS FUZZ CRASHED MY WHOLE IRIX SYSTEM after "ENTER"! :-(
-                                          # PROCESS IN ITSELF RUNS OK, WITH LARGER BUFFSIZES THOUGH.
-                                          # OH MAYBE IT WAS BECAUSE DEBUGGING WAS ON???
-                                          # ANYWAY, I'M NOT GONNA RUN THAT AGAIN... WAY TOO DANGEROUS!
-TESTH   = $(PAINC)
-
-all: patest
-
-# "cc" for the MIPSpro compiler, may be changed to "gcc":
-patest: $(TESTC) $(TESTH) Makefile
-       cc $(CFLAGS) $(TESTC) $(CDEFINES) $(LIBS) -o patest
-
-run: patest
-       ./patest
-
diff --git a/pa_sgi/pthread-pa_sgi.c b/pa_sgi/pthread-pa_sgi.c
deleted file mode 100644 (file)
index e9ab273..0000000
+++ /dev/null
@@ -1,908 +0,0 @@
-/*
- * PortAudio Portable Real-Time Audio Library
- * Latest Version at: http://www.portaudio.com
- * SGI IRIX implementation by Pieter Suurmond, september 22, 2001 (#0.18).
- *
- * Copyright (c) 1999-2001 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.
- */
-/*
-Modfication History:
-  8/12/2001 - Pieter Suurmond - took the v15 pa_linux_oss.c file and started to adapt for IRIX 6.2.
-  8/17/2001 - alpha release with IRIX sproc()-method, may sometimes let IRIX6.2 crash at closing audiostream.
-  9/22/2001 - #0.18 pthread starts to work a bit:
-              BUT UNDER IRIX6.2, I DON'T GET IT TO WORK REALLY CORRECTLY,
-                                 this POSIX-attempt,
-              DON'T USE THIS FILE FOR RELIABLE OPERATION, IT IS HERE JUST 
-              FOR DOCUMENTATION/ARCHIVE... OR FOR ANYONE WHO WANTS TO FIX......
-TODO:
-  - Test under IRIX 6.5.
-  - Dynamically switch to 32 bit float as native format when appropriate (let SGI do the conversion), 
-    and maybe also the other natively supported formats? (might increase performance)
-  - Not sure whether CPU UTILIZATION MEASUREMENT (from OSS/linux) really works. Changed nothing yet,
-    seems ok, but I've not yet tested it thoroughly. (maybe utilization-code may be made _unix_common_ then?)
-  - The minimal number of buffers setting... I do not yet fully understand it.. I now just take *4.
-REFERENCES:
-  - IRIX 6.2 man pages regarding SGI AL library.
-  - IRIS Digital MediaProgramming Guide (online books as well as man-pages come with IRIX 6.2 and 
-    may not be publically available on the internet).
-*/
-
-#include <stdio.h>              /* Standard libraries. */
-#include <stdlib.h>
-
-#include "../pa_common/portaudio.h"     /* Portaudio headers. */
-#include "../pa_common/pa_host.h"
-#include "../pa_common/pa_trace.h"
-
-/*
-#include <malloc.h>
-#include <memory.h>
-#include <sys/prctl.h>          Not needed
-#include <sys/types.h>
-#include <sys/schedctl.h>
-#include <signal.h>
-#include <sys/ioctl.h>           Needed? 
-#include <sys/time.h>
-#include <sched.h>               sched_param struct and related functions  
-                                 used in setting thread priorities.        
-#include <limits.h>              Some POSIX constants such as _POSIX_THREAD_THREADS_MAX
-*/
-
-#include <pthread.h>            /* Pthreads are supported by IRIX 6.2 after       */
-                                /* patches 1361, 1367, and 1429 are applied.      */
-                                
-#include <fcntl.h>              /* fcntl.h needed for "O_RDONLY". */
-#include <unistd.h>             /* For usleep() and constants used when calling sysconf() */
-                                /* to query POSIX limits (see the sysconf(3) ref. page.   */
-
-#include <dmedia/audio.h>       /* SGI-specific audio library.    */
-
-
-/*--------------------------------------------*/
-#define PRINT(x)   { printf x; fflush(stdout); }
-#define ERR_RPT(x) PRINT(x)
-#define DBUG(x)    PRINT(x)
-#define DBUGX(x)   /* PRINT(x) */
-
-#define MAX_CHARS_DEVNAME           (16)        /* Was 32 in OSS (20 for AL but "in"/"out" is concat. */
-#define MAX_SAMPLE_RATES            (8)         /* Known from SGI AL there are 7 (was 10 in OSS v15). */
-
-typedef struct                    internalPortAudioDevice                 /* IRIX specific device info:      */
-{
-  PaDeviceID           /* NEW: */ pad_DeviceID;                           /* THIS "ID" IS NEW HERE (Pieter)! */
-  long                            pad_ALdevice;                           /* SGI-number!                     */
-  double                          pad_SampleRates[MAX_SAMPLE_RATES];      /* for pointing to from pad_Info   */
-  char                            pad_DeviceName[MAX_CHARS_DEVNAME+1];    /* +1 for \0, one more than OSS.   */
-  PaDeviceInfo                    pad_Info;                               /* pad_Info (v15) contains:        */
-                                     /* int            structVersion;                                           */
-                                     /* const char*    name;                                                    */
-                                     /* int            maxInputChannels, maxOutputChannels;                     */
-                                     /* int            numSampleRates;       Num rates, or -1 if range supprtd. */
-                                  /* const double*  sampleRates;          Array of supported sample rates,   */
-                                     /* PaSampleFormat nativeSampleFormats;  or {min,max} if range supported.   */
-  struct internalPortAudioDevice* pad_Next;                               /* Singly linked list, (NULL=end). */
-} internalPortAudioDevice;
-
-typedef struct      PaHostSoundControl              /* Structure to contain all SGI IRIX specific data. */
-{
-  ALport            pahsc_ALportIN,                 /* IRIX-audio-library-datatype. ALports can only be */
-                    pahsc_ALportOUT;                /* unidirectional, so we sometimes need 2 of them.  */
-  pthread_t         pahsc_ThreadPID;
-  short             *pahsc_NativeInputBuffer,       /* Allocated here, in this file, if necessary.      */
-                    *pahsc_NativeOutputBuffer;
-  unsigned int      pahsc_BytesPerInputBuffer,      /* Native buffer sizes in bytes, really needed here */
-                    pahsc_BytesPerOutputBuffer;     /* to free FAST memory, if buffs were alloctd FAST. */
-  unsigned int      pahsc_SamplesPerInputBuffer,    /* These amounts are needed again and again in the  */
-                    pahsc_SamplesPerOutputBuffer;   /* audio-thread (don't need to be kept globally).   */
-  struct itimerval  pahsc_EntryTime,                /* For measuring CPU utilization (same as linux).   */
-                    pahsc_LastExitTime;
-  long              pahsc_InsideCountSum,
-                    pahsc_TotalCountSum;
-} PaHostSoundControl;
-
-/*----------------------------- Shared Data ------------------------------------------------------*/
-static internalPortAudioDevice* sDeviceList = NULL; /* FIXME - put Mutex around this shared data. */
-static int                      sPaHostError = 0;   /* Maybe more than one process writing errs!? */
-
-long Pa_GetHostError(void)
-{
-    return (long)sPaHostError;
-}
-
-/*----------------------------- BEGIN CPU UTILIZATION MEASUREMENT -----------------*/
-/*                              (copied from source pa_linux_oss/pa_linux_oss.c)   */
-static void Pa_StartUsageCalculation( internalPortAudioStream   *past )
-{
-       struct itimerval itimer;
-       PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;
-       if( pahsc == NULL ) return;
-/* Query system timer for usage analysis and to prevent overuse of CPU. */
-       getitimer( ITIMER_REAL, &pahsc->pahsc_EntryTime );
-}
-
-static long SubtractTime_AminusB( struct itimerval *timeA, struct itimerval *timeB )
-{
-       long secs = timeA->it_value.tv_sec - timeB->it_value.tv_sec;
-       long usecs = secs * 1000000;
-       usecs += (timeA->it_value.tv_usec - timeB->it_value.tv_usec);
-       return usecs;
-}
-
-static void Pa_EndUsageCalculation( internalPortAudioStream   *past )
-{
-       struct  itimerval currentTime;
-       long    insideCount;
-       long    totalCount;       /* Measure CPU utilization during this callback. */
-
-#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 (getitimer( ITIMER_REAL, &currentTime ) == 0 )
-           {
-               if (past->past_IfLastExitValid)
-                   {
-                       insideCount = SubtractTime_AminusB( &pahsc->pahsc_EntryTime, &currentTime );
-                       pahsc->pahsc_InsideCountSum += insideCount;
-                       totalCount =  SubtractTime_AminusB( &pahsc->pahsc_LastExitTime, &currentTime );
-                       pahsc->pahsc_TotalCountSum += totalCount;
-               /*  DBUG(("insideCount = %d, totalCount = %d\n", insideCount, totalCount )); */
-            /* Low pass filter the result because sometimes we get called several times in a row. */
-            /* That can cause the TotalCount to be very low which can cause the usage to appear   */
-            /* unnaturally high. So we must filter numerator and denominator separately!!!        */
-                       if (pahsc->pahsc_InsideCountSum > 0)
-                           {
-                               past->past_AverageInsideCount = ((LOWPASS_COEFFICIENT_0 * past->past_AverageInsideCount) +
-                                                                    (LOWPASS_COEFFICIENT_1 * pahsc->pahsc_InsideCountSum));
-                               past->past_AverageTotalCount  = ((LOWPASS_COEFFICIENT_0 * past->past_AverageTotalCount) +
-                                                                    (LOWPASS_COEFFICIENT_1 * pahsc->pahsc_TotalCountSum));
-                               past->past_Usage = past->past_AverageInsideCount / past->past_AverageTotalCount;
-                               pahsc->pahsc_InsideCountSum = 0;
-                               pahsc->pahsc_TotalCountSum = 0;
-                           }
-                   }
-               past->past_IfLastExitValid = 1;
-           }
-       pahsc->pahsc_LastExitTime.it_value.tv_sec = 100;
-       pahsc->pahsc_LastExitTime.it_value.tv_usec = 0;
-       setitimer( ITIMER_REAL, &pahsc->pahsc_LastExitTime, NULL );
-       past->past_IfLastExitValid = 1;
-}   /*----------- END OF CPU UTILIZATION CODE (from pa_linux_oss/pa_linux_oss.c v15)--------------------*/
-
-
-/*--------------------------------------------------------------------------------------*/
-PaError translateSGIerror(void) /* Calls oserror(), may be used after an SGI AL-library */
-{                               /* call to report via ERR_RPT(), yields a PaError-num.  */
-    const char* a = "SGI AL ";  /* (Not absolutely sure errno came from THIS thread!    */
-    switch(oserror())           /* Read IRIX man-pages about the _SGI_MP_SOURCE macro.) */
-        {
-        case AL_BAD_OUT_OF_MEM:
-             ERR_RPT(("%sout of memory.\n", a)); 
-             return paInsufficientMemory;                   /* Known PaError.   */
-        case AL_BAD_CONFIG:
-             ERR_RPT(("%sconfiguration invalid or NULL.\n", a));
-             return paHostError;                            /* Generic PaError. */
-        case AL_BAD_CHANNELS:
-             ERR_RPT(("%schannels not 1,2 or 4.\n", a));
-             return paHostError;                            /* Generic PaError. */
-        case AL_BAD_NO_PORTS:
-             ERR_RPT(("%sout of audio ports.\n", a));
-             return paHostError;                            /* Generic PaError. */
-        case AL_BAD_DEVICE:
-             ERR_RPT(("%swrong device number.\n", a));
-             return paHostError;                            /* Generic PaError. */
-        case AL_BAD_DEVICE_ACCESS:
-             ERR_RPT(("%swrong device access.\n", a));
-             return paHostError;                            /* Generic PaError. */
-        case AL_BAD_DIRECTION:
-             ERR_RPT(("%sinvalid direction.\n", a));
-             return paHostError;                            /* Generic PaError. */
-        case AL_BAD_SAMPFMT:
-             ERR_RPT(("%sdoesn't accept sampleformat.\n", a));
-             return paHostError;                            /* Generic PaError. */
-        case AL_BAD_FLOATMAX:
-             ERR_RPT(("%smax float value is zero.\n", a));
-             return paHostError;                            /* Generic PaError. */
-        case AL_BAD_WIDTH:
-             ERR_RPT(("%sunsupported samplewidth.\n", a));
-             return paHostError;                            /* Generic PaError. */
-        case AL_BAD_QSIZE:
-             ERR_RPT(("%sinvalid queue size.\n", a));
-             return paHostError;                            /* Generic PaError. */
-        case AL_BAD_PVBUFFER:
-             ERR_RPT(("%sPVbuffer null.\n", a));
-             return paHostError;                            /* Generic PaError. */
-        case AL_BAD_BUFFERLENGTH_NEG:
-             ERR_RPT(("%snegative bufferlength.\n", a));
-             return paHostError;                            /* Generic PaError. */
-        case AL_BAD_BUFFERLENGTH_ODD:
-             ERR_RPT(("%sodd bufferlength.\n", a));
-             return paHostError;                            /* Generic PaError. */
-        case AL_BAD_PARAM:
-             ERR_RPT(("%sparameter not valid for device.\n", a));
-             return paHostError;                            /* Generic PaError. */
-        default:
-             ERR_RPT(("%sunknown error.\n", a));
-             return paHostError;                            /* Generic PaError. */
-        }
-}
-
-/*------------------------------------------------------------------------------------------*/
-/* Tries to set various rates and formats and fill in the device info structure.            */
-static PaError Pa_sgiQueryDevice(long                     ALdev,  /* (AL_DEFAULT_DEVICE)    */
-                                 PaDeviceID               id,     /* (DefaultI|ODeviceID()) */
-                                 char*                    name,   /* (for example "SGI AL") */
-                                 internalPortAudioDevice* pad)    /* Result written to pad. */
-{
-       int     format;
-    long    min, max;                           /* To catch hardware characteristics.       */
-    ALseterrorhandler(0);                       /* 0 = turn off the default error handler.  */
-    /*--------------------------------------------------------------------------------------*/
-    pad->pad_ALdevice = ALdev;                              /* Set the AL device number.    */
-    pad->pad_DeviceID = id;                                 /* Set the PA device number.    */
-    if (strlen(name) > MAX_CHARS_DEVNAME)                   /* MAX_CHARS defined above.     */
-        {
-        ERR_RPT(("Pa_QueryDevice(): name too long (%s).\n", name));
-        return paHostError;
-        }
-    strcpy(pad->pad_DeviceName, name);                      /* Write name-string.           */
-       pad->pad_Info.name = pad->pad_DeviceName;               /* Set pointer,..hmmm.          */
-    /*--------------------------------- natively supported sample formats: -----------------*/
-    pad->pad_Info.nativeSampleFormats = paInt16; /* Later also include paFloat32 | ..| etc. */
-                                                 /* Then also choose other CallConvertXX()! */
-    /*--------------------------------- number of available i/o channels: ------------------*/
-    if (ALgetminmax(ALdev, AL_INPUT_COUNT, &min, &max))
-        return translateSGIerror();
-       pad->pad_Info.maxInputChannels = max;
-       DBUG(("Pa_QueryDevice: maxInputChannels = %d\n", pad->pad_Info.maxInputChannels))
-    if (ALgetminmax(ALdev, AL_OUTPUT_COUNT, &min, &max))
-        return translateSGIerror();
-       pad->pad_Info.maxOutputChannels = max;
-       DBUG(("Pa_QueryDevice: maxOutputChannels = %d\n", pad->pad_Info.maxOutputChannels))
-    /*--------------------------------- supported samplerates: ----------------------*/ 
-       pad->pad_Info.numSampleRates = 7;   
-       pad->pad_Info.sampleRates = pad->pad_SampleRates;
-    pad->pad_SampleRates[0] = (double)AL_RATE_8000;     /* long -> double. */
-    pad->pad_SampleRates[1] = (double)AL_RATE_11025;
-    pad->pad_SampleRates[2] = (double)AL_RATE_16000;
-    pad->pad_SampleRates[3] = (double)AL_RATE_22050;
-    pad->pad_SampleRates[4] = (double)AL_RATE_32000;
-    pad->pad_SampleRates[5] = (double)AL_RATE_44100;
-    pad->pad_SampleRates[6] = (double)AL_RATE_48000;
-    if (ALgetminmax(ALdev, AL_INPUT_RATE, &min, &max))  /* Ask INPUT rate-max.       */
-        return translateSGIerror();                     /* double -> long.           */
-    if (max != (long)(0.5 + pad->pad_SampleRates[6]))   /* FP-compare not recommndd. */
-        goto weird;
-    if (ALgetminmax(ALdev, AL_OUTPUT_RATE, &min, &max)) /* Ask OUTPUT rate-max.      */
-        return translateSGIerror();
-    if (max != (long)(0.5 + pad->pad_SampleRates[6]))
-        {
-weird:  ERR_RPT(("Pa_sgiQueryDevice() did not confirm max samplerate (%ld)\n",max));
-        return paHostError;             /* Or make it a warning and just carry on... */
-        }
-    /*-------------------------------------------------------------------------------*/ 
-       return paNoError;
-}
-
-
-/*--------------------------------------------------------------------------------*/
-int Pa_CountDevices()       /* Name of this function suggests it only counts and  */
-{                           /* is NOT destructive, it however resets whole PA !   */   
-    int                        numDevices = 0;        /* Let 's not do that here. */
-    internalPortAudioDevice*   currentDevice = sDeviceList;   /* COPY GLOBAL VAR. */
-#if 0                       /* Remains from linux_oss v15: Pa_Initialize(), on    */
-    if (!currentDevice)     /* its turn, calls PaHost_Init() via file pa_lib.c.   */
-        Pa_Initialize();    /* Isn't that a bit too 'rude'?        Don't be too   */
-#endif                      /* friendly to clients that forgot to initialize PA.  */
-    while (currentDevice)   /* Slower but more elegant than the sNumDevices-way:  */
-        {
-        numDevices++;
-        currentDevice = currentDevice->pad_Next;
-        }
-       return numDevices;
-}
-
-/*-------------------------------------------------------------------------------*/
-static internalPortAudioDevice *Pa_GetInternalDevice(PaDeviceID id)
-{
-    int                         numDevices = 0;
-    internalPortAudioDevice     *res = (internalPortAudioDevice*)NULL;
-       internalPortAudioDevice     *pad = sDeviceList;         /* COPY GLOBAL VAR.  */
-    while (pad)                         /* pad may be NULL, that's ok, return 0. */
-        {  /* (Added ->pad_DeviceID field to the pad-struct, Pieter, 2001.)      */
-        if (pad->pad_DeviceID == id)    /* This the device we were looking for?  */
-            res = pad;                  /* But keep on(!) counting so we don't   */
-        numDevices++;                   /* have to call Pa_CountDevices() later. */
-        pad = pad->pad_Next;            /* Advance to the next device or NULL.   */
-        }                               /* No assumptions about order of ID's in */
-    if (!res)                           /* the list.                             */
-        ERR_RPT(("Pa_GetInternalDevice() could not find specified ID (%d).\n",id));
-    if ((id < 0) || (id >= numDevices))
-        {
-        ERR_RPT(("Pa_GetInternalDevice() supplied with an illegal ID (%d).\n",id));
-#if 1                                             /* Be strict, even when found, */
-        res = (internalPortAudioDevice*)NULL;     /* do not accept illegal ID's. */
-#endif
-        }
-       return res;
-}
-
-/*----------------------------------------------------------------------*/
-const PaDeviceInfo* Pa_GetDeviceInfo(PaDeviceID id)
-{
-    PaDeviceInfo*             res = (PaDeviceInfo*)NULL;
-       internalPortAudioDevice*  pad = Pa_GetInternalDevice(id);  /* Call. */
-    if (pad)
-           res = &pad->pad_Info;   /* Not finding the specified ID is not  */
-    if (!res)                   /* the same as &pad->pad_Info == NULL.  */
-        ERR_RPT(("Pa_GetDeviceInfo() could not find it (ID=%d).\n", id));
-    return res;                 /* So (maybe) a second/third ERR_RPT(). */
-}
-
-/*------------------------------------------------*/
-PaDeviceID Pa_GetDefaultInputDeviceID(void)
-{
-       return 0;       /* 0 is the default device ID. */
-}
-/*------------------------------------------------*/
-PaDeviceID Pa_GetDefaultOutputDeviceID(void)
-{
-       return 0;
-}
-
-/*-------------------------------------------------------------------------------------------------*/
-/* Build linked a list with all the available audio devices on this SGI machine (only 1 for now).  */
-PaError PaHost_Init(void)                              /* Called by Pa_Initialize() from pa_lib.c. */
-{
-    internalPortAudioDevice*    pad;
-       PaError                     r = paNoError;
-    int                         audioLibFileID;             /* To test for the presence of audio.  */
-
-    if (sDeviceList)                                        /* Allow re-init, only warn, no error. */
-        {
-        ERR_RPT(("Warning: PaHost_Init() did not really re-init PA.\n"));
-        return r;
-        }
-    /*------------- ADD THE SGI DEFAULT DEVICE TO THE LIST: ---------------------------------------*/
-    audioLibFileID = open("/dev/hdsp/hdsp0master", O_RDONLY);   /* Try to open Indigo style audio  */
-    if (audioLibFileID < 0)                                     /* IO port. On failure, machine    */
-        {                                                       /* has no audio ability.           */
-        ERR_RPT(("PaHost_Init(): This machine has no (Indigo-style) audio abilities.\n"));
-        return paHostError;
-        }
-    close(audioLibFileID);                              /* Allocate fast mem to hold device info.  */
-       pad = PaHost_AllocateFastMemory(sizeof(internalPortAudioDevice));
-       if (pad == NULL)
-        return paInsufficientMemory;
-    memset(pad, 0, sizeof(internalPortAudioDevice));    /* "pad->pad_Next = NULL" is more elegant. */
-       r = Pa_sgiQueryDevice(AL_DEFAULT_DEVICE,            /* Set AL device num (AL_DEFAULT_DEVICE).  */
-                          Pa_GetDefaultOutputDeviceID(),/* Set PA device num (or InputDeviceID()). */
-                          "AL default",                 /* A suitable name.                        */
-                          pad);                         /* Write args and queried info into pad.   */
-       if (r != paNoError)
-               {
-        ERR_RPT(("Pa_QueryDevice for '%s' returned: %d\n", pad->pad_DeviceName, r));
-               PaHost_FreeFastMemory(pad, sizeof(internalPortAudioDevice));   /* sDeviceList still NULL ! */
-               }
-    else
-        sDeviceList = pad;            /* First element in linked list. pad->pad_Next already NULL. */
-    /*------------- QUERY AND ADD MORE POSSIBLE SGI DEVICES TO THE LINKED LIST: -------------------*/
-    /*---------------------------------------------------------------------------------------------*/
-       return r;
-}
-
-/*---------------------------------------------------------------------------------------------------*/
-static PaError Pa_SgiAudioProcess(internalPortAudioStream *past) /* Spawned by PaHost_StartEngine(). */
-{
-    PaError                 result = paNoError;
-    PaHostSoundControl      *pahsc;
-    
-    if (!past)
-        return paBadStreamPtr;
-    pahsc = (PaHostSoundControl*)past->past_DeviceData;
-       if (!pahsc)
-        return paInternalError;
-       past->past_IsActive = 1;            /* Wasn't this already done by the calling parent?!   */
-    DBUG(("entering thread.\n"));
-
-    while (!past->past_StopSoon)        /* OR-ing StopSoon and StopNow here gives problems! */
-        {
-        /*---------------------------------------- INPUT: ------------------------------------*/
-        if (pahsc->pahsc_NativeInputBuffer)     /* Then pahsc_ALportIN should also be there!  */
-            {
-            while (ALgetfilled(pahsc->pahsc_ALportIN) < pahsc->pahsc_SamplesPerInputBuffer)
-                {
-                /* Trying sginap(1); and usleep(); here... things get blocked under IRIX6.2. */
-                if (past->past_StopNow)    /* Don't let ALreadsamps() block */
-                    goto done;
-                }
-            if (ALreadsamps(pahsc->pahsc_ALportIN, (void*)pahsc->pahsc_NativeInputBuffer,
-                            pahsc->pahsc_SamplesPerInputBuffer))    /* Number of samples instead  */
-                {                                                   /* of number of frames.       */
-                ERR_RPT(("ALreadsamps() failed.\n"));
-                result =  paInternalError;
-                goto done;
-                }
-            }
-        /*---------------------------------------------------- USER CALLBACK ROUTINE: ----------*/
-        /* DBUG(("Calling Pa_CallConvertInt16()...\n")); */
-        Pa_StartUsageCalculation(past);                     /* Convert 16 bit native data to    */
-           result = Pa_CallConvertInt16(past,                  /* user data and call user routine. */
-                                                pahsc->pahsc_NativeInputBuffer, pahsc->pahsc_NativeOutputBuffer);
-           Pa_EndUsageCalculation(past);
-           if (result) 
-                   {
-                       DBUG(("Pa_CallConvertInt16() returned %d, stopping...\n", result));
-            goto done;                      /* This is apparently NOT an error!       */
-                   }                               /* Just letting the userCallBack stop us. */
-        /*---------------------------------------- OUTPUT: ------------------------------------*/
-        if (pahsc->pahsc_NativeOutputBuffer)    /* Then pahsc_ALportOUT should also be there!  */
-            {
-            while (ALgetfillable(pahsc->pahsc_ALportOUT) < pahsc->pahsc_SamplesPerOutputBuffer)
-                {
-                /* Trying sginap(1); and usleep(); here... things get blocked under IRIX6.2. */
-                if (past->past_StopNow)    /* Don't let ALwritesamps() block */
-                    goto done;
-                }
-            if (ALwritesamps(pahsc->pahsc_ALportOUT, (void*)pahsc->pahsc_NativeOutputBuffer,
-                             pahsc->pahsc_SamplesPerOutputBuffer))
-                {
-                ERR_RPT(("ALwritesamps() failed.\n"));
-                result = paInternalError;
-                goto done;
-                }
-            }
-        /*-------------------------------------------------------------------------------------*/
-        }
-done:
-    /* pahsc->pahsc_ThreadPID = -1;   Hu? doesn't help!! (added by Pieter) */
-    past->past_IsActive = 0;
-    DBUG(("leaving thread.\n"));
-    return result;
-}
-
-
-/*--------------------------------------------------------------------------------------*/
-PaError PaHost_OpenStream(internalPortAudioStream *past)
-{
-       PaError                 result = paNoError;
-       PaHostSoundControl      *pahsc;
-       unsigned int            minNumBuffers;
-       internalPortAudioDevice *padIN, *padOUT;        /* For looking up native AL-numbers. */
-    ALconfig                sgiALconfig = NULL;     /* IRIX-datatype.   */
-    long                    pvbuf[8];               /* To get/set hardware configs.      */
-    long                    sr, ALqsize;
-    DBUG(("PaHost_OpenStream() called.\n"));        /* Alloc FASTMEM and init host data. */
-    if (!past)
-        {
-        ERR_RPT(("Streampointer NULL!\n"));
-        result = paBadStreamPtr;        goto done;
-        }
-       pahsc = (PaHostSoundControl*)PaHost_AllocateFastMemory(sizeof(PaHostSoundControl));
-       if (pahsc == NULL)
-           {
-        ERR_RPT(("FAST Memory allocation failed.\n"));  /* Pass trough some ERR_RPT-exit-  */
-        result = paInsufficientMemory;  goto done;      /* code (nothing will be freed).   */
-           }
-       memset(pahsc, 0, sizeof(PaHostSoundControl));
-/*  pahsc->pahsc_threadPID = -1;                       Should pahsc_threadPID be inited to */
-       past->past_DeviceData = (void*)pahsc;           /* -1 instead of 0 ??                  */
-    /*--------------------------------------------------- Allocate native buffers: --------*/
-    pahsc->pahsc_SamplesPerInputBuffer = past->past_FramesPerUserBuffer * /* Needed by the */
-                                         past->past_NumInputChannels;     /* audio-thread. */
-       pahsc->pahsc_BytesPerInputBuffer   = pahsc->pahsc_SamplesPerInputBuffer * sizeof(short);
-       if (past->past_NumInputChannels > 0)                       /* Assumes short = 16 bits! */
-           {
-               pahsc->pahsc_NativeInputBuffer = (short*)PaHost_AllocateFastMemory(pahsc->pahsc_BytesPerInputBuffer);        
-               if( pahsc->pahsc_NativeInputBuffer == NULL )
-                   {
-            ERR_RPT(("Fast memory allocation for input-buffer failed.\n"));
-                       result = paInsufficientMemory;  goto done;
-                   }
-           }
-    pahsc->pahsc_SamplesPerOutputBuffer = past->past_FramesPerUserBuffer * /* Needed by the */
-                                          past->past_NumOutputChannels;    /* audio-thread. */
-       pahsc->pahsc_BytesPerOutputBuffer   = pahsc->pahsc_SamplesPerOutputBuffer * sizeof(short);
-       if (past->past_NumOutputChannels > 0)                       /* Assumes short = 16 bits! */
-           {
-               pahsc->pahsc_NativeOutputBuffer = (short*)PaHost_AllocateFastMemory(pahsc->pahsc_BytesPerOutputBuffer);
-               if (pahsc->pahsc_NativeOutputBuffer == NULL)
-                   {
-            ERR_RPT(("Fast memory allocation for output-buffer failed.\n"));
-                       result = paInsufficientMemory;  goto done;
-                   }
-           }
-    /*------------------------------------------ Manipulate hardware if necessary and allowed: --*/
-    ALseterrorhandler(0);                           /* 0 = turn off the default error handler.   */
-    pvbuf[0] = AL_INPUT_RATE;
-    pvbuf[2] = AL_INPUT_COUNT;
-    pvbuf[4] = AL_OUTPUT_RATE;              /* TO FIX: rates may be logically, not always in Hz! */
-    pvbuf[6] = AL_OUTPUT_COUNT;
-    sr = (long)(past->past_SampleRate + 0.5);   /* Common for input and output :-)               */
-    if (past->past_NumInputChannels > 0)                        /* We need to lookup the corre-  */
-        {                                                       /* sponding native AL-number(s). */
-        padIN = Pa_GetInternalDevice(past->past_InputDeviceID);
-        if (!padIN)
-            {
-            ERR_RPT(("Pa_GetInternalDevice() for input failed.\n"));
-               result = paHostError;  goto done;
-            }
-        if (ALgetparams(padIN->pad_ALdevice, &pvbuf[0], 4)) /* Although input and output will both be on */
-            goto sgiError;                                  /* the same AL-device, the AL-library might  */
-        if (pvbuf[1] != sr)                                 /* contain more than AL_DEFAULT_DEVICE in    */
-            {  /* Rate different from current harware-rate?    the future. Therefore 2 seperate queries. */
-            if (pvbuf[3] > 0)     /* Means, there's other clients using AL-input-ports */
-                {
-                ERR_RPT(("Sorry, not allowed to switch input-hardware to %ld Hz because \
-another process is currently using input at %ld kHz.\n", sr, pvbuf[1]));
-                result = paHostError;   goto done;
-                }
-            pvbuf[1] = sr;                  /* Then set input-rate. */
-            if (ALsetparams(padIN->pad_ALdevice, &pvbuf[0], 2))
-                goto sgiError;      /* WHETHER THIS SAMPLERATE WAS REALLY PRESENT IN OUR ARRAY OF RATES, */
-            }                       /* IS NOT CHECKED, AT LEAST NOT BY ME, WITHIN THIS FILE! Does PA do? */
-        }
-    if (past->past_NumOutputChannels > 0)           /* CARE: padOUT/IN may NOT be NULL if Channels <= 0! */
-        {                                           /* We use padOUT/IN later on, or at least 1 of both. */
-        padOUT = Pa_GetInternalDevice(past->past_OutputDeviceID);
-        if (!padOUT)
-            {
-            ERR_RPT(("Pa_GetInternalDevice() for output failed.\n"));
-               result = paHostError;  goto done;
-            }
-        if (ALgetparams(padOUT->pad_ALdevice,&pvbuf[4], 4))
-            goto sgiError;
-        if ((past->past_NumOutputChannels > 0) && (pvbuf[5] != sr))
-            {   /* Output needed and rate different from current harware-rate. */
-            if (pvbuf[7] > 0)     /* Means, there's other clients using AL-output-ports */
-                {
-                ERR_RPT(("Sorry, not allowed to switch output-hardware to %ld Hz because \
-another process is currently using output at %ld kHz.\n", sr, pvbuf[5]));            
-                result = paHostError;   goto done;      /* Will free again the inputbuffer */
-                }                                       /* that was just created above.    */
-            pvbuf[5] = sr;                  /* Then set output-rate. */
-            if (ALsetparams(padOUT->pad_ALdevice, &pvbuf[4], 2))
-                goto sgiError;
-            }
-        }
-    /*------------------------------------------ Construct an audio-port-configuration ----------*/
-    sgiALconfig = ALnewconfig();                    /* Change the SGI-AL-default-settings.       */
-    if (sgiALconfig == (ALconfig)0)                 /* sgiALconfig is released here after use!   */
-        goto sgiError;                              /* See that sgiALconfig is NOT released!     */
-    if (ALsetsampfmt(sgiALconfig, AL_SAMPFMT_TWOSCOMP))  /* Choose paInt16 as native i/o-format. */
-        goto sgiError;
-    if (ALsetwidth (sgiALconfig, AL_SAMPLE_16))     /* Only meaningful when sample format for    */
-        goto sgiError;                              /* config is set to two's complement format. */
-    /************************ Future versions might (dynamically) switch to 32-bit floats? *******
-    if (ALsetsampfmt(sgiALconfig, AL_SAMPFMT_FLOAT))    (Then also call another CallConvert-func.)
-        goto sgiError;
-    if (ALsetfloatmax (sgiALconfig, 1.0))       Only meaningful when sample format for config 
-        goto sgiError;                          is set to AL_SAMPFMT_FLOAT or AL_SAMPFMT_DOUBLE. */
-    /*---------- ?? --------------------*/
-       /* 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;
-    /*------------------------------------------------ Set internal AL queuesize (in samples) ----*/
-    if (pahsc->pahsc_SamplesPerInputBuffer >= pahsc->pahsc_SamplesPerOutputBuffer)
-        ALqsize = (long)pahsc->pahsc_SamplesPerInputBuffer;
-    else                                            /* Take the largest of the two amounts.       */
-        ALqsize = (long)pahsc->pahsc_SamplesPerOutputBuffer;
-    ALqsize *= 4;                                   /* 4 times as large as amount per transfer!   */    
-    if (ALsetqueuesize(sgiALconfig, ALqsize))       /* Or should we use past_NumUserBuffers here? */
-        goto sgiError;                              /* Using 2 times may give glitches... */
-    /* Have to work on ALsetqueuesize() above. */
-
-    /* Do ALsetchannels() later, apart per input and/or output. */
-    /*----------------------------------------------- OPEN 1 OR 2 AL-DEVICES: --------------------*/
-       if (past->past_OutputDeviceID == past->past_InputDeviceID)  /* Who SETS these devive-numbers? */
-           {
-               if ((past->past_NumOutputChannels > 0) && (past->past_NumInputChannels > 0))
-                   {
-            DBUG(("PaHost_OpenStream: opening both input and output channels.\n"));
-            /*------------------------- open output port: ----------------------------------*/
-            if (ALsetchannels (sgiALconfig, (long)(past->past_NumOutputChannels)))
-                goto sgiError;                      /* Returns 0 on success, -1 on failure. */
-            pahsc->pahsc_ALportOUT = ALopenport("PA sgi out", "w", sgiALconfig);
-            if (pahsc->pahsc_ALportOUT == (ALport)0)
-                goto sgiError;
-            /*------------------------- open input port: -----------------------------------*/
-            if (ALsetchannels (sgiALconfig, (long)(past->past_NumInputChannels)))
-                goto sgiError;                      /* Returns 0 on success, -1 on failure. */
-            pahsc->pahsc_ALportIN = ALopenport("PA sgi in", "r", sgiALconfig);
-            if (pahsc->pahsc_ALportIN == (ALport)0)
-                goto sgiError;          /* For some reason the "patest_wire.c"-test crashes! */
-                   }                           /* Probably due to too small buffersizes?....        */
-        else
-            {
-            ERR_RPT(("Cannot setup bidirectional stream between different devices.\n"));
-            result = paHostError;
-            goto done;
-            }
-           }
-       else /* (OutputDeviceID != InputDeviceID) */
-           {
-               if (past->past_NumOutputChannels > 0)   /* WRITE-ONLY: */
-                   {       
-            /*------------------------- open output port: ----------------------------------*/
-            DBUG(("PaHost_OpenStream: opening %d output channel(s) on %s.\n",
-                 past->past_NumOutputChannels, padOUT->pad_DeviceName));
-            if (ALsetchannels (sgiALconfig, (long)(past->past_NumOutputChannels)))
-                goto sgiError;                      /* Returns 0 on success, -1 on failure. */
-            pahsc->pahsc_ALportOUT = ALopenport("PA sgi out", "w", sgiALconfig);
-            if (pahsc->pahsc_ALportOUT == (ALport)0)
-                goto sgiError;
-                   }
-               if (past->past_NumInputChannels > 0)   /* READ-ONLY: */
-                   {       
-            /*------------------------- open input port: -----------------------------------*/
-            DBUG(("PaHost_OpenStream: opening %d input channel(s) on %s.\n",
-                 past->past_NumInputChannels, padIN->pad_DeviceName));
-            if (ALsetchannels (sgiALconfig, (long)(past->past_NumInputChannels)))
-                goto sgiError;                      /* Returns 0 on success, -1 on failure. */
-            pahsc->pahsc_ALportIN = ALopenport("PA sgi in", "r", sgiALconfig);
-            if (pahsc->pahsc_ALportIN == (ALport)0)
-                goto sgiError;
-                   }
-           }
-       DBUG(("PaHost_OpenStream() succeeded.\n"));
-    goto done;  /* (no errors occured) */
-sgiError:   
-    result = translateSGIerror();   /* Translates SGI AL-code to PA-code and ERR_RPTs string. */
-done:
-    if (sgiALconfig)
-        ALfreeconfig(sgiALconfig);              /* We don't need that struct anymore. */
-    if (result != paNoError)
-        PaHost_CloseStream(past);               /* Frees memory (only if really allocated!).  */
-    return result;
-}
-
-/*-----------------------------------------------------*/
-PaError PaHost_StartOutput(internalPortAudioStream *past)
-{
-       return paNoError;   /* Hmm, not implemented yet? */
-}
-PaError PaHost_StartInput(internalPortAudioStream *past)
-{
-       return paNoError;
-}
-
-/*------------------------------------------------------------------------------*/
-PaError PaHost_StartEngine(internalPortAudioStream *past)
-{
-       PaHostSoundControl  *pahsc;
-    int                 hres;
-    PaError             result = paNoError;
-
-    if (!past)          /* Test argument. */
-        {
-        ERR_RPT(("PaHost_StartEngine(NULL)!\n"));
-        return paBadStreamPtr;
-        }
-    pahsc = (PaHostSoundControl*)past->past_DeviceData;
-    if (!pahsc)
-        {
-        ERR_RPT(("PaHost_StartEngine(arg): arg->past_DeviceData == NULL!\n"));
-        return paHostError;
-        }
-       past->past_StopSoon = 0;            /* Assume SGI ALport is already opened! */
-       past->past_StopNow  = 0;
-    past->past_IsActive = 1;
-    DBUG(("PaHost_StartEngine() called.\n"));
-    /* Use pthread_create() instead of __clone() because:                         */
-    /* - pthread_create also works for other UNIX systems like Solaris,           */
-    /* - Java HotSpot VM crashes in pthread_setcanceltype() when using __clone(). */
-       hres = pthread_create(&(pahsc->pahsc_ThreadPID),    /* SPAWN AUDIO-CHILD.     */
-                                 NULL,                         /* pthread_attr_t * attr  */
-                                 (void*)Pa_SgiAudioProcess,
-                          past);
-       if (hres)
-           {
-               result = paHostError;
-               sPaHostError = hres;
-        ERR_RPT(("PaHost_StartEngine() failed to spawn audio-thread.\n"));
-           }
-    return result;
-}
-
-/*------------------------------------------------------------------------------*/
-PaError PaHost_StopEngine(internalPortAudioStream *past, int abort)
-{
-       int                 hres;
-       PaError             result = paNoError;
-       PaHostSoundControl  *pahsc;
-    
-    DBUG(("PaHost_StopEngine() called.\n"));
-    if (!past)
-        return paBadStreamPtr;
-    pahsc = (PaHostSoundControl*)past->past_DeviceData;
-       if (pahsc == NULL)
-        return result;                  /* paNoError (already stopped, no err?).       */
-    past->past_StopSoon = 1;            /* Tell background thread to stop generating   */
-    if (abort)                          /* more and to let current data play out. If   */
-        past->past_StopNow = 1;         /* aborting, tell backgrnd thread to stop NOW! */
-       if (pahsc->pahsc_ThreadPID != -1)   /* Join thread to recover memory resources.    */
-           {
-        DBUG(("pthread_join() called.\n"));
-               hres = pthread_join(pahsc->pahsc_ThreadPID, NULL);
-               if (hres)
-                   {
-                       result = paHostError;
-                       sPaHostError = hres;
-            ERR_RPT(("PaHost_StopEngine() failed pthread_join().\n"));
-                   }
-               pahsc->pahsc_ThreadPID = -1;
-           }
-    past->past_IsActive = 0;
-       return result;
-}
-
-/*---------------------------------------------------------------*/
-PaError PaHost_StopOutput(internalPortAudioStream *past, int abort)
-{
-       return paNoError;                   /* Not implemented yet? */
-}
-PaError PaHost_StopInput(internalPortAudioStream *past, int abort )
-{
-       return paNoError;
-}
-
-/*******************************************************************/
-PaError PaHost_CloseStream(internalPortAudioStream *past)
-{
-       PaHostSoundControl  *pahsc;
-    PaError             result = paNoError;
-    
-    DBUG(("PaHost_CloseStream() called.\n"));
-       if (past == NULL)
-        return paBadStreamPtr;
-       pahsc = (PaHostSoundControl *) past->past_DeviceData;
-       if (pahsc == NULL)          /* If pahsc not NULL, past_DeviceData will be freed, and set to NULL. */
-        return result;          /* This test prevents from freeing NULL-pointers. */
-
-    if (pahsc->pahsc_ALportIN)
-        {
-        if (ALcloseport(pahsc->pahsc_ALportIN))
-            result = translateSGIerror();   /* Translates SGI AL-code to PA-code and ERR_RPTs string. */
-        else                                /* But go on anyway... to release other stuff... */
-            pahsc->pahsc_ALportIN = (ALport)0;
-        }
-    if (pahsc->pahsc_ALportOUT)
-        {
-        if (ALcloseport(pahsc->pahsc_ALportOUT))
-            result = translateSGIerror();
-        else
-            pahsc->pahsc_ALportOUT = (ALport)0;
-        }
-       if (pahsc->pahsc_NativeInputBuffer)
-           {
-        PaHost_FreeFastMemory(pahsc->pahsc_NativeInputBuffer, pahsc->pahsc_BytesPerInputBuffer);        
-               pahsc->pahsc_NativeInputBuffer = NULL;
-           }
-       if (pahsc->pahsc_NativeOutputBuffer)
-           {
-        PaHost_FreeFastMemory(pahsc->pahsc_NativeOutputBuffer, pahsc->pahsc_BytesPerOutputBuffer);
-               pahsc->pahsc_NativeOutputBuffer = NULL;
-           }
-       PaHost_FreeFastMemory(pahsc, sizeof(PaHostSoundControl));
-    past->past_DeviceData = NULL;                       /* PaHost_OpenStream() allocated FAST. */
-       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 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.
-*/
-#define PA_LATENCY_ENV_NAME  ("PA_MIN_LATENCY_MSEC")
-
-int Pa_GetMinNumBuffers( int framesPerBuffer, double sampleRate )
-{
-       return 2;
-}
-/* Hmmm, the note above isn't appropriate for SGI I'm afraid... */
-/* Do we HAVE to do it this way under IRIX???....               */
-/*--------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------*/
-PaError PaHost_Term(void)   /* Frees all of the linked audio-devices.  */
-{                           /* Called by Pa_Terminate() from pa_lib.c. */
-       internalPortAudioDevice *pad = sDeviceList,
-                            *nxt;
-       while (pad)
-           {
-               DBUG(("PaHost_Term: freeing %s\n", pad->pad_DeviceName));
-        nxt = pad->pad_Next;
-               PaHost_FreeFastMemory(pad, sizeof(internalPortAudioDevice));
-               pad = nxt;              /* PaHost_Init allocated this FAST MEM.*/
-           }
-       sDeviceList = (internalPortAudioDevice*)NULL;
-       return 0;                           /* Got rid of       sNumDevices=0; */
-}
-
-/***********************************************************************/
-void Pa_Sleep( long msec )  /* Sleep requested number of milliseconds. */
-{
-#if 0
-       struct timeval timeout;
-       timeout.tv_sec = msec / 1000;
-       timeout.tv_usec = (msec % 1000) * 1000;
-       select(0, NULL, NULL, NULL, &timeout);
-#else
-       long usecs = msec * 1000;
-       usleep( usecs );
-#endif
-}
-
-/*---------------------------------------------------------------------------------------*/
-/* Allocate memory that can be accessed in real-time. This may need to be held in physi- */
-/* cal memory so that it is not paged to virtual memory. This call MUST be balanced with */
-/* a call to PaHost_FreeFastMemory().                                                    */
-void *PaHost_AllocateFastMemory(long numBytes)
-{
-       void *addr = malloc(numBytes);
-       if (addr)
-        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, long numBytes)
-{
-       if (addr)
-        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);
-}
-
-/*-------------------------------------------------------------------*/
-PaTimestamp Pa_StreamTime( PortAudioStream *stream )
-{
-       internalPortAudioStream *past = (internalPortAudioStream *) stream; 
-/* FIXME - return actual frames played, not frames generated.
-** Need to query the output device somehow.
-*/
-       return past->past_FrameCount;
-}
diff --git a/pa_tests/debug_convert.c b/pa_tests/debug_convert.c
deleted file mode 100644 (file)
index a17b556..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * $Id$
- * Convert tagged values.
- *
- * Author: Phil Burk <philburk@softsynth.com>
- *
- * This program uses the PortAudio Portable Audio Library.
- * For more information see: http://www.portaudio.com
- * 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 <math.h>
-#include "portaudio.h"
-#define OUTPUT_DEVICE       (Pa_GetDefaultOutputDeviceID())
-//#define OUTPUT_DEVICE       (11)
-#define NUM_SECONDS         (8)
-#define SLEEP_DUR           (800)
-#define SAMPLE_RATE         (44100)
-#define FRAMES_PER_BUFFER   (256)
-
-#define NUM_BUFFERS         (0)
-
-typedef struct
-{
-    unsigned int framesToGo;
-}
-paTestData;
-/* This routine will be called by the PortAudio engine when audio is needed.
-** It may called at interrupt level on some machines so don't do anything
-** that could mess up the system like calling malloc() or free().
-*/
-static int patestCallback( void *inputBuffer, void *outputBuffer,
-                           unsigned long framesPerBuffer,
-                           PaTimestamp outTime, void *userData )
-{
-    paTestData *data = (paTestData*)userData;
-    short *out = (short*)outputBuffer;
-    int i;
-    int finished = 0;
-    (void) outTime; /* Prevent unused variable warnings. */
-    (void) inputBuffer;
-
-    if( data->framesToGo < framesPerBuffer )  finished = 1;
-
-    for( i=0; i<framesPerBuffer; i++ )
-    {
-        *out++ = 0x0000 + i;  /* left */
-        *out++ = 0x1000 + i;  /* right */
-    }
-    return finished;
-}
-/*******************************************************************/
-int main(void);
-int main(void)
-{
-    PortAudioStream *stream;
-    PaError err;
-    paTestData data;
-    int i;
-    int totalSamps;
-    printf("PortAudio Test: output debug values\n" );
-    data.framesToGo = totalSamps =  NUM_SECONDS * SAMPLE_RATE; /* Play for a few seconds. */
-    printf("totalSamps = %d\n", totalSamps );
-    err = Pa_Initialize();
-    if( err != paNoError ) goto error;
-    printf("PortAudio Test: output device = %d\n", OUTPUT_DEVICE );
-    
-    err = Pa_OpenStream(
-              &stream,
-              paNoDevice,
-              0,              /* no input */
-              paFloat32,  /* 32 bit floating point input */
-              NULL,
-              OUTPUT_DEVICE,
-              2,              /* stereo output */
-              paInt16,      /* 32 bit floating point output */
-              NULL,
-              SAMPLE_RATE,
-              FRAMES_PER_BUFFER,
-              NUM_BUFFERS,    /* number of buffers, if zero then use default minimum */
-              paClipOff|paDitherOff, /* we won't output out of range samples so don't bother clipping them */
-              patestCallback,
-              &data );
-    if( err != paNoError ) goto error;
-    
-    err = Pa_StartStream( stream );
-    if( err != paNoError ) goto error;
-    printf("Is callback being called?\n");
-    for( i=0; i<((NUM_SECONDS+1)*1000); i+=SLEEP_DUR )
-    {
-        printf("data.framesToGo = %d\n", data.framesToGo ); fflush(stdout);
-        Pa_Sleep( SLEEP_DUR );
-    }
-    /* Stop sound until ENTER hit. */
-    printf("Call Pa_StopStream()\n");
-    err = Pa_StopStream( stream );
-    if( err != paNoError ) goto error;
-    Pa_Terminate();
-    printf("Test finished.\n");
-    return err;
-error:
-    Pa_Terminate();
-    fprintf( stderr, "An error occured while using the portaudio stream\n" );
-    fprintf( stderr, "Error number: %d\n", err );
-    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
-    return err;
-}
diff --git a/pa_tests/debug_dither_calc.c b/pa_tests/debug_dither_calc.c
deleted file mode 100644 (file)
index 1b24760..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * $Id$
- * Test Dither calculations.
- *
- * Author: Phil Burk  http://www.softsynth.com
- *
- * This program uses the PortAudio Portable Audio Library.
- * For more information see: http://www.portaudio.com
- * 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 <math.h>
-#include "portaudio.h"
-#include "pa_host.h"
-
-/*******************************************************************/
-int main(void);
-int main(void)
-{
-    long max,min;
-    int   i;
-    
-    for( i=0; i<10000; i++ )
-    {
-        long dither = PaConvert_TriangularDither();
-        // printf("dither = 0x%08X\n", dither );
-        if( dither < min ) min = dither;
-        else if( dither > max ) max = dither;
-    }
-    printf("min = 0x%08X = %d, max = 0x%08X = %d\n", min, min, max, max );
-}
index d230833203d1e67faac6a0eee6b7c66f4e429311..4817a11434df2b3881fa974dfc2a544d242a413b 100644 (file)
@@ -1,8 +1,9 @@
 /*
  * $Id$
- * debug_multi_out.c
- * Play a different sine wave on each channels,
+ * debug_multi.c
+ * Play a sine wave on each of multiple channels,
  * using the Portable Audio api.
+ * Hacked test for debugging PA.
  *
  * Author: Phil Burk  http://www.softsynth.com
  *
 #include <stdio.h>
 #include <math.h>
 #include "portaudio.h"
-
-#define OUTPUT_DEVICE       (Pa_GetDefaultOutputDeviceID())
+#define NUM_CHANNELS        (8)
+// #define OUTPUT_DEVICE       (Pa_GetDefaultOutputDeviceID())
+#define OUTPUT_DEVICE       (18)
+#define NUM_SECONDS         (NUM_CHANNELS*4)
 #define SAMPLE_RATE         (44100)
+#define FRAMES_PER_CHANNEL  (SAMPLE_RATE/2)
 #define FRAMES_PER_BUFFER   (256)
-#define FREQ_INCR           (300.0 / SAMPLE_RATE)
-#define MAX_CHANNELS        (64)
-
+#define MIN_LATENCY_MSEC    (400)
+#define NUM_BUFFERS         ((MIN_LATENCY_MSEC * SAMPLE_RATE) / (FRAMES_PER_BUFFER * 1000))
 #ifndef M_PI
 #define M_PI  (3.14159265)
 #endif
-
+#define TABLE_SIZE   (800)
 typedef struct
 {
-    int      numChannels;
-    double   phases[MAX_CHANNELS];
+    float sine[TABLE_SIZE];
+    int   phase;
+    int   liveChannel;
+    int   count;
+    unsigned int sampsToGo;
 }
 paTestData;
-
 /* This routine will be called by the PortAudio engine when audio is needed.
 ** It may called at interrupt level on some machines so don't do anything
 ** that could mess up the system like calling malloc() or free().
@@ -65,25 +70,38 @@ static int patestCallback( void *inputBuffer, void *outputBuffer,
 {
     paTestData *data = (paTestData*)userData;
     float *out = (float*)outputBuffer;
-    int frameIndex, channelIndex;
+    int i, j;
     int finished = 0;
     (void) outTime; /* Prevent unused variable warnings. */
     (void) inputBuffer;
 
-    for( frameIndex=0; frameIndex<(int)framesPerBuffer; frameIndex++ )
+    if( data->sampsToGo < framesPerBuffer )
     {
-        for( channelIndex=0; channelIndex<data->numChannels; channelIndex++ )
+        finished = 1;
+    }
+    else
+    {
+        for( i=0; i<(int)framesPerBuffer; i++ )
         {
-            /* Output sine wave on every channel. */
-            *out++ = (float) sin(data->phases[channelIndex]);
-
-            /* Play each channel at a higher frequency. */
-            data->phases[channelIndex] += FREQ_INCR * (4 + channelIndex);
-            if( data->phases[channelIndex] >= (2.0 * M_PI) ) data->phases[channelIndex] -= (2.0 * M_PI);
+            for( j=0; j<NUM_CHANNELS; j++ )
+            {
+                /* Output sine wave only on live channel. */
+                *out++ = (j==data->liveChannel) ? data->sine[data->phase] : 0.0f;
+                /* Play each channel at a higher frequency. */
+                data->phase += 1 + data->liveChannel;
+                if( data->phase >= TABLE_SIZE ) data->phase -= TABLE_SIZE;
+            }
+            /* Switch channels every so often. */
+            if( --data->count <= 0 )
+            {
+                data->count = FRAMES_PER_CHANNEL;
+                data->liveChannel += 1;
+                if( data->liveChannel >= NUM_CHANNELS ) data->liveChannel = 0;
+            }
         }
+        data->sampsToGo -= framesPerBuffer;
     }
-
-    return 0;
+    return finished;
 }
 /*******************************************************************/
 int main(void);
@@ -91,18 +109,21 @@ int main(void)
 {
     PortAudioStream *stream;
     PaError err;
-    const PaDeviceInfo *pdi;
-    paTestData data = {0};
-    printf("PortAudio Test: output sine wave on each channel.\n" );
-
+    paTestData data;
+    int i;
+    int totalSamps;
+    printf("PortAudio Test: output sine wave. %d buffers\n", NUM_BUFFERS );
+    /* initialise sinusoidal wavetable */
+    for( i=0; i<TABLE_SIZE; i++ )
+    {
+        data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
+    }
+    data.phase = 0;
+    data.count = FRAMES_PER_CHANNEL;
+    data.liveChannel = 0;
+    data.sampsToGo = totalSamps =  NUM_SECONDS * SAMPLE_RATE; /* Play for a few seconds. */
     err = Pa_Initialize();
     if( err != paNoError ) goto error;
-
-    pdi = Pa_GetDeviceInfo( OUTPUT_DEVICE );
-    data.numChannels = pdi->maxOutputChannels;
-    if( data.numChannels > MAX_CHANNELS ) data.numChannels = MAX_CHANNELS;
-    printf("Number of Channels = %d\n", data.numChannels );
-    
     err = Pa_OpenStream(
               &stream,
               paNoDevice, /* default input device */
@@ -110,27 +131,27 @@ int main(void)
               paFloat32,  /* 32 bit floating point input */
               NULL,
               OUTPUT_DEVICE,
-              data.numChannels,
+              NUM_CHANNELS,
               paFloat32,  /* 32 bit floating point output */
               NULL,
               SAMPLE_RATE,
               FRAMES_PER_BUFFER,  /* frames per buffer */
-              0,    /* number of buffers, if zero then use default minimum */
+              NUM_BUFFERS,    /* number of buffers, if zero then use default minimum */
               paClipOff,      /* we won't output out of range samples so don't bother clipping them */
               patestCallback,
               &data );
     if( err != paNoError ) goto error;
-
     err = Pa_StartStream( stream );
     if( err != paNoError ) goto error;
-
-    printf("Hit ENTER to stop sound.\n");
-    fflush(stdout);
-    getchar();
-
+    printf("Is callback being called?\n");
+    for( i=0; i<NUM_SECONDS; i++ )
+    {
+        printf("data.sampsToGo = %d\n", data.sampsToGo );
+        Pa_Sleep( 1000 );
+    }
+    /* Stop sound until ENTER hit. */
     err = Pa_StopStream( stream );
     if( err != paNoError ) goto error;
-
     Pa_CloseStream( stream );
     Pa_Terminate();
     printf("Test finished.\n");
index 57b11f581fc7d42f1c4e2839c5f3524f9521a151..fd4118e963e6a3e3d6ed5443ef6daeaadd3de839 100644 (file)
 #define SAMPLE_RATE     (22050)
 #define NUM_SECONDS     (10)
 #define SLEEP_DUR_MSEC  (200)
-#define FRAMES_PER_BUFFER  (1<<10)
+#define REC_BUF_FRAMES  (1<<10)
 #define NUM_REC_BUFS    (0)
-
-#if 1
+#if 0
 #define PA_SAMPLE_TYPE  paFloat32
 typedef float SAMPLE;
 #else
 #define PA_SAMPLE_TYPE  paInt16
 typedef short SAMPLE;
 #endif
-
 typedef struct
 {
     long         frameIndex;  /* Index into sample array. */
     long         maxFrameIndex;
     long         samplesPerFrame;
-    long         numSamples;
     SAMPLE      *recordedSamples;
 }
 paTestData;
@@ -156,19 +153,41 @@ static int playCallback( void *inputBuffer, void *outputBuffer,
     }
     return finished;
 }
-
-/****************************************************************/
-PaError TestRecording( paTestData *dataPtr )
+/*******************************************************************/
+int main(void);
+int main(void)
 {
     PortAudioStream *stream;
     PaError    err;
-    int        i;
+    paTestData data;
+    long       totalFrames;
+    long       numSamples;
+    long       numBytes;
+    long       i;
+    printf("patest_record.c\n"); fflush(stdout);
+
+    data.frameIndex = 0;
+    data.samplesPerFrame = 2;
+    data.maxFrameIndex = totalFrames = NUM_SECONDS*SAMPLE_RATE;
+
+    printf("totalFrames = %d\n", totalFrames ); fflush(stdout);
+    numSamples = totalFrames * data.samplesPerFrame;
+    numBytes = numSamples * sizeof(SAMPLE);
+    data.recordedSamples = (SAMPLE *) malloc( numBytes );
+    if( data.recordedSamples == NULL )
+    {
+        printf("Could not allocate record array.\n");
+        exit(1);
+    }
+    for( i=0; i<numSamples; i++ ) data.recordedSamples[i] = 0;
+    err = Pa_Initialize();
+    if( err != paNoError ) goto error;
 
     /* Record some audio. */
     err = Pa_OpenStream(
               &stream,
               Pa_GetDefaultInputDeviceID(),
-              dataPtr->samplesPerFrame,               /* stereo input */
+              data.samplesPerFrame,               /* stereo input */
               PA_SAMPLE_TYPE,
               NULL,
               paNoDevice,
@@ -176,15 +195,14 @@ PaError TestRecording( paTestData *dataPtr )
               PA_SAMPLE_TYPE,
               NULL,
               SAMPLE_RATE,
-              FRAMES_PER_BUFFER,            /* frames per buffer */
+              REC_BUF_FRAMES,            /* frames per buffer */
               NUM_REC_BUFS,               /* number of buffers, if zero then use default minimum */
               paClipOff,       /* we won't output out of range samples so don't bother clipping them */
               recordCallback,
-              dataPtr );
+              &data );
     if( err != paNoError ) goto error;
     err = Pa_StartStream( stream );
     if( err != paNoError ) goto error;
-
     printf("Now recording!\n"); fflush(stdout);
     for( i=0; i<(NUM_SECONDS*1000/SLEEP_DUR_MSEC); i++ )
     {
@@ -193,64 +211,18 @@ PaError TestRecording( paTestData *dataPtr )
             printf("Stream inactive!\n");
             break;
         }
-        if( dataPtr->maxFrameIndex <= dataPtr->frameIndex )
+        if( data.maxFrameIndex <= data.frameIndex )
         {
             printf("Buffer recording complete.\n");
             break;
         }
         Pa_Sleep(100);
-        printf("index = %d\n", dataPtr->frameIndex ); fflush(stdout);
+        printf("index = %d\n", data.frameIndex );
     }
-
-    printf("Finished loop. Close stream.\n"); fflush(stdout);
-
     err = Pa_CloseStream( stream );
     if( err != paNoError ) goto error;
-
-    printf("Done.\n"); fflush(stdout);
-    {
-        SAMPLE max = 0;
-        SAMPLE posVal;
-        int i;
-        for( i=0; i<dataPtr->numSamples; i++ )
-        {
-            posVal = dataPtr->recordedSamples[i];
-            if( posVal < 0 ) posVal = -posVal;
-            if( posVal > max ) max = posVal;
-        }
-        printf("Largest recorded sample = %d\n", max );
-    }
-    /* Write recorded data to a file. */
-#if 0
-    {
-        FILE  *fid;
-        fid = fopen("recorded.raw", "wb");
-        if( fid == NULL )
-        {
-            printf("Could not open file.");
-        }
-        else
-        {
-            fwrite( dataPtr->recordedSamples, dataPtr->samplesPerFrame * sizeof(SAMPLE), totalFrames, fid );
-            fclose( fid );
-            printf("Wrote data to 'recorded.raw'\n");
-        }
-    }
-#endif
-
-error:
-    return err;
-}
-
-/****************************************************************/
-PaError TestPlayback( paTestData *dataPtr )
-{
-    PortAudioStream *stream;
-    PaError    err;
-    int        i;
-
     /* Playback recorded data. */
-    dataPtr->frameIndex = 0;
+    data.frameIndex = 0;
     printf("Begin playback.\n"); fflush(stdout);
     err = Pa_OpenStream(
               &stream,
@@ -259,15 +231,15 @@ PaError TestPlayback( paTestData *dataPtr )
               PA_SAMPLE_TYPE,
               NULL,
               Pa_GetDefaultOutputDeviceID(),
-              dataPtr->samplesPerFrame,               /* stereo output */
+              data.samplesPerFrame,               /* stereo output */
               PA_SAMPLE_TYPE,
               NULL,
               SAMPLE_RATE,
-              FRAMES_PER_BUFFER,            /* frames per buffer */
+              1024,            /* frames per buffer */
               0,               /* number of buffers, if zero then use default minimum */
               paClipOff,       /* we won't output out of range samples so don't bother clipping them */
               playCallback,
-              dataPtr );
+              &data );
     if( err != paNoError ) goto error;
     err = Pa_StartStream( stream );
     if( err != paNoError ) goto error;
@@ -275,57 +247,43 @@ PaError TestPlayback( paTestData *dataPtr )
     for( i=0; i<(NUM_SECONDS*1000/SLEEP_DUR_MSEC); i++ )
     {
         Pa_Sleep(100);
-        printf("index = %d\n", dataPtr->frameIndex );
+        printf("index = %d\n", data.frameIndex );
     }
     err = Pa_CloseStream( stream );
     if( err != paNoError ) goto error;
-    
-error:
-    return err;
-}
-/*******************************************************************/
-int main(void);
-int main(void)
-{
-    PaError    err;
-    paTestData data;
-    long       totalFrames;
-    long       numBytes;
-    long       i;
-    printf("patest_record.c\n"); fflush(stdout);
-
-    data.frameIndex = 0;
-    data.samplesPerFrame = 2;
-    data.maxFrameIndex = totalFrames = NUM_SECONDS*SAMPLE_RATE;
-
-    printf("totalFrames = %d\n", totalFrames ); fflush(stdout);
-    data.numSamples = totalFrames * data.samplesPerFrame;
-
-    numBytes = data.numSamples * sizeof(SAMPLE);
-    data.recordedSamples = (SAMPLE *) malloc( numBytes );
-    if( data.recordedSamples == NULL )
+    printf("Done.\n"); fflush(stdout);
     {
-        printf("Could not allocate record array.\n");
-        exit(1);
+        SAMPLE max = 0;
+        SAMPLE posVal;
+        int i;
+        for( i=0; i<numSamples; i++ )
+        {
+            posVal = data.recordedSamples[i];
+            if( posVal < 0 ) posVal = -posVal;
+            if( posVal > max ) max = posVal;
+        }
+        printf("Largest recorded sample = %d\n", max );
     }
-    for( i=0; i<data.numSamples; i++ ) data.recordedSamples[i] = 0;
-
-    err = Pa_Initialize();
-    if( err != paNoError ) goto error;
-
-    for( i=0; i<2; i++ )
+    /* Write recorded data to a file. */
+#if 0
     {
-        err = TestRecording( &data );
-        if( err != paNoError ) goto error;
-
-        err = TestPlayback( &data );
-        if( err != paNoError ) goto error;
+        FILE  *fid;
+        fid = fopen("recorded.raw", "wb");
+        if( fid == NULL )
+        {
+            printf("Could not open file.");
+        }
+        else
+        {
+            fwrite( data.recordedSamples, data.samplesPerFrame * sizeof(SAMPLE), totalFrames, fid );
+            fclose( fid );
+            printf("Wrote data to 'recorded.raw'\n");
+        }
     }
-
+#endif
     free( data.recordedSamples );
     Pa_Terminate();
     return 0;
-
 error:
     Pa_Terminate();
     fprintf( stderr, "An error occured while using the portaudio stream\n" );
diff --git a/pa_tests/debug_record_reuse.c b/pa_tests/debug_record_reuse.c
deleted file mode 100644 (file)
index 46f937d..0000000
+++ /dev/null
@@ -1,351 +0,0 @@
-/*
- * $Id$
- * debug_record_reuse.c
- * Record input into an array.
- * Save array to a file.
- * Based on patest_record.c but with various ugly debug hacks thrown in.
- * Loop twice and reuse same streams.
- *
- * Author: Phil Burk  http://www.softsynth.com
- *
- * This program uses the PortAudio Portable Audio Library.
- * For more information see: http://www.portaudio.com
- * 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 <memory.h>
-#include "portaudio.h"
-#define SAMPLE_RATE     (22050)
-#define NUM_SECONDS     (4)
-#define SLEEP_DUR_MSEC  (200)
-#define FRAMES_PER_BUFFER  (256)
-#define NUM_REC_BUFS    (0)
-
-#if 1
-#define PA_SAMPLE_TYPE  paFloat32
-typedef float SAMPLE;
-#else
-#define PA_SAMPLE_TYPE  paInt16
-typedef short SAMPLE;
-#endif
-
-typedef struct
-{
-    long         frameIndex;  /* Index into sample array. */
-    long         maxFrameIndex;
-    long         samplesPerFrame;
-    long         numSamples;
-    PortAudioStream *outputStream;
-    PortAudioStream *inputStream;
-    SAMPLE      *recordedSamples;
-}
-paTestData;
-
-/* This routine will be called by the PortAudio engine when audio is needed.
-** It may be called at interrupt level on some machines so don't do anything
-** that could mess up the system like calling malloc() or free().
-*/
-static int recordCallback( void *inputBuffer, void *outputBuffer,
-                           unsigned long framesPerBuffer,
-                           PaTimestamp outTime, void *userData )
-{
-    paTestData *data = (paTestData*)userData;
-    SAMPLE *rptr = (SAMPLE*)inputBuffer;
-    SAMPLE *wptr = &data->recordedSamples[data->frameIndex * data->samplesPerFrame];
-    long framesToCalc;
-    unsigned long i;
-    int finished;
-    unsigned long framesLeft = data->maxFrameIndex - data->frameIndex;
-
-    (void) outputBuffer; /* Prevent unused variable warnings. */
-    (void) outTime;
-
-    if( framesLeft < framesPerBuffer )
-    {
-        framesToCalc = framesLeft;
-        finished = 1;
-    }
-    else
-    {
-        framesToCalc = framesPerBuffer;
-        finished = 0;
-    }
-    if( inputBuffer == NULL )
-    {
-        for( i=0; i<framesToCalc; i++ )
-        {
-            *wptr++ = 0;  /* left */
-            *wptr++ = 0;  /* right */
-        }
-    }
-    else
-    {
-        for( i=0; i<framesToCalc; i++ )
-        {
-            *wptr++ = *rptr++;  /* left */
-            *wptr++ = *rptr++;  /* right */
-        }
-    }
-    data->frameIndex += framesToCalc;
-    return finished;
-}
-
-/* This routine will be called by the PortAudio engine when audio is needed.
-** It may be called at interrupt level on some machines so don't do anything
-** that could mess up the system like calling malloc() or free().
-*/
-static int playCallback( void *inputBuffer, void *outputBuffer,
-                         unsigned long framesPerBuffer,
-                         PaTimestamp outTime, void *userData )
-{
-    paTestData *data = (paTestData*)userData;
-    SAMPLE *rptr = &data->recordedSamples[data->frameIndex * data->samplesPerFrame];
-    SAMPLE *wptr = (SAMPLE*)outputBuffer;
-    unsigned long i;
-    int finished;
-    unsigned int framesLeft = data->maxFrameIndex - data->frameIndex;
-    if( outputBuffer == NULL ) return 0;
-    (void) inputBuffer; /* Prevent unused variable warnings. */
-    (void) outTime;
-
-    if( framesLeft < framesPerBuffer )
-    {
-        /* final buffer... */
-        for( i=0; i<framesLeft; i++ )
-        {
-            *wptr++ = *rptr++;  /* left */
-            *wptr++ = *rptr++;  /* right */
-        }
-        for( ; i<framesPerBuffer; i++ )
-        {
-            *wptr++ = 0;  /* left */
-            *wptr++ = 0;  /* right */
-        }
-        data->frameIndex += framesLeft;
-        finished = 1;
-    }
-    else
-    {
-        for( i=0; i<framesPerBuffer; i++ )
-        {
-            *wptr++ = *rptr++;  /* left */
-            *wptr++ = *rptr++;  /* right */
-        }
-        data->frameIndex += framesPerBuffer;
-        finished = 0;
-    }
-    return finished;
-}
-
-/****************************************************************/
-PaError TestRecording( paTestData *dataPtr )
-{
-    PaError    err;
-    int        i;
-    int        lastIndex = 0;
-
-/* Open input stream if not already open. */
-    if( dataPtr->inputStream == NULL )
-    {
-        /* Record some audio. */
-        err = Pa_OpenStream(
-                  &dataPtr->inputStream,
-                  Pa_GetDefaultInputDeviceID(),
-                  dataPtr->samplesPerFrame,               /* stereo input */
-                  PA_SAMPLE_TYPE,
-                  NULL,
-                  paNoDevice,
-                  0,
-                  PA_SAMPLE_TYPE,
-                  NULL,
-                  SAMPLE_RATE,
-                  FRAMES_PER_BUFFER,            /* frames per buffer */
-                  NUM_REC_BUFS,               /* number of buffers, if zero then use default minimum */
-                  paClipOff,       /* we won't output out of range samples so don't bother clipping them */
-                  recordCallback,
-                  dataPtr );
-        if( err != paNoError ) goto error;
-    }
-
-    dataPtr->frameIndex = 0;
-
-    err = Pa_StartStream( dataPtr->inputStream );
-    if( err != paNoError ) goto error;
-
-    printf("Now recording!\n"); fflush(stdout);
-    for( i=0; i<(NUM_SECONDS*1000/SLEEP_DUR_MSEC); i++ )
-    {
-        int frameIndex, delta;
-        Pa_Sleep(SLEEP_DUR_MSEC);
-
-        frameIndex = dataPtr->frameIndex;
-        if( Pa_StreamActive( dataPtr->inputStream ) <= 0)
-        {
-            printf("Stream inactive!\n");
-            break;
-        }
-        if( dataPtr->maxFrameIndex <= frameIndex )
-        {
-            printf("Buffer recording complete.\n");
-            break;
-        }
-
-        delta = frameIndex - lastIndex;
-        lastIndex = frameIndex;
-        printf("index = %d, delta = %d\n", frameIndex, delta ); fflush(stdout);
-    }
-
-    err = Pa_StopStream( dataPtr->inputStream );
-    if( err != paNoError ) goto error;
-
-    printf("Done.\n"); fflush(stdout);
-
-error:
-    return err;
-}
-
-/****************************************************************/
-PaError TestPlayback( paTestData *dataPtr )
-{
-    PaError    err;
-    int        i;
-    int        lastIndex = 0;
-
-    /* Playback recorded data. */
-    dataPtr->frameIndex = 0;
-    printf("Begin playback.\n"); fflush(stdout);
-
-/* Open output stream if not already open. */
-    if( dataPtr->outputStream == NULL )
-    {
-        err = Pa_OpenStream(
-                  &dataPtr->outputStream,
-                  paNoDevice,
-                  0,               /* NO input */
-                  PA_SAMPLE_TYPE,
-                  NULL,
-                  Pa_GetDefaultOutputDeviceID(),
-                  dataPtr->samplesPerFrame,               /* stereo output */
-                  PA_SAMPLE_TYPE,
-                  NULL,
-                  SAMPLE_RATE,
-                  FRAMES_PER_BUFFER,            /* frames per buffer */
-                  0,               /* number of buffers, if zero then use default minimum */
-                  paClipOff,       /* we won't output out of range samples so don't bother clipping them */
-                  playCallback,
-                  dataPtr );
-        if( err != paNoError ) goto error;
-    }
-
-    err = Pa_StartStream( dataPtr->outputStream );
-    if( err != paNoError ) goto error;
-
-    printf("Waiting for playback to finish.\n"); fflush(stdout);
-    for( i=0; i<(NUM_SECONDS*1000/SLEEP_DUR_MSEC); i++ )
-    {
-        int frameIndex, delta;
-        Pa_Sleep(SLEEP_DUR_MSEC);
-        frameIndex = dataPtr->frameIndex;
-        delta = frameIndex - lastIndex;
-        lastIndex = frameIndex;
-        printf("index = %d, delta = %d\n", frameIndex, delta ); fflush(stdout);
-    }
-
-    err = Pa_StopStream( dataPtr->outputStream );
-    if( err != paNoError ) goto error;
-    
-error:
-    return err;
-}
-/*******************************************************************/
-int main(void);
-int main(void)
-{
-    PaError    err;
-    paTestData data = { 0 };
-    long       totalFrames;
-    long       numBytes;
-    long       i;
-    printf("patest_record.c\n"); fflush(stdout);
-
-/* Set up test data structure and sample array. */
-    data.frameIndex = 0;
-    data.samplesPerFrame = 2;
-    data.maxFrameIndex = totalFrames = NUM_SECONDS*SAMPLE_RATE;
-
-    printf("totalFrames = %d\n", totalFrames ); fflush(stdout);
-    data.numSamples = totalFrames * data.samplesPerFrame;
-
-    numBytes = data.numSamples * sizeof(SAMPLE);
-    data.recordedSamples = (SAMPLE *) malloc( numBytes );
-    if( data.recordedSamples == NULL )
-    {
-        printf("Could not allocate record array.\n");
-        exit(1);
-    }
-    for( i=0; i<data.numSamples; i++ ) data.recordedSamples[i] = 0;
-
-    err = Pa_Initialize();
-    if( err != paNoError ) goto error;
-
-/* Record and playback multiple times. */
-    for( i=0; i<2; i++ )
-    {
-        err = TestRecording( &data );
-        if( err != paNoError ) goto error;
-
-        err = TestPlayback( &data );
-        if( err != paNoError ) goto error;
-    }
-
-/* Clean up. */
-    err = Pa_CloseStream( data.inputStream );
-    if( err != paNoError ) goto error;
-
-    err = Pa_CloseStream( data.outputStream );
-    if( err != paNoError ) goto error;
-
-    if( err != paNoError ) goto error;
-
-    free( data.recordedSamples );
-    Pa_Terminate();
-    
-    printf("Test complete.\n"); fflush(stdout);
-    return 0;
-
-error:
-    Pa_Terminate();
-    fprintf( stderr, "An error occured while using the portaudio stream\n" );
-    fprintf( stderr, "Error number: %d\n", err );
-    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
-    if( err == paHostError )
-    {
-        fprintf( stderr, "Host Error number: %d\n", Pa_GetHostError() );
-    }
-    return -1;
-}
index 86610d3f6adc4582bcdc059730d1f59a8185f048..b79405dbbe66a5c1f6b785bcde796f18337b8d47 100644 (file)
@@ -43,7 +43,7 @@
 #define SLEEP_DUR           (800)
 #define SAMPLE_RATE         (44100)
 #define FRAMES_PER_BUFFER   (256)
-#if 0
+#if 1
 #define MIN_LATENCY_MSEC    (200)
 #define NUM_BUFFERS         ((MIN_LATENCY_MSEC * SAMPLE_RATE) / (FRAMES_PER_BUFFER * 1000))
 #else
diff --git a/pa_tests/debug_sine_amp.c b/pa_tests/debug_sine_amp.c
deleted file mode 100644 (file)
index ceaf572..0000000
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * $Id$
- * Play a different sine wave on each channels,
- * using the Portable Audio api.
- * Allos amplitude to be set interactively.
- *
- * Author: Phil Burk  http://www.softsynth.com
- *
- * This program uses the PortAudio Portable Audio Library.
- * For more information see: http://www.portaudio.com
- * 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 <math.h>
-#include "portaudio.h"
-
-#define OUTPUT_DEVICE       (Pa_GetDefaultOutputDeviceID())
-#define SAMPLE_RATE         (44100)
-#define FRAMES_PER_BUFFER   (256)
-#define FREQ_INCR           (300.0 / SAMPLE_RATE)
-#define MAX_CHANNELS        (64)
-
-#ifndef M_PI
-#define M_PI  (3.14159265)
-#endif
-
-typedef struct
-{
-    int      numChannels;
-    double   phases[MAX_CHANNELS];
-    float    amplitude;
-}
-paTestData;
-
-/* This routine will be called by the PortAudio engine when audio is needed.
-** It may called at interrupt level on some machines so don't do anything
-** that could mess up the system like calling malloc() or free().
-*/
-static int patestCallback( void *inputBuffer, void *outputBuffer,
-                           unsigned long framesPerBuffer,
-                           PaTimestamp outTime, void *userData )
-{
-    paTestData *data = (paTestData*)userData;
-    float *out = (float*)outputBuffer;
-    int frameIndex, channelIndex;
-    (void) outTime; /* Prevent unused variable warnings. */
-    (void) inputBuffer;
-
-    for( frameIndex=0; frameIndex<(int)framesPerBuffer; frameIndex++ )
-    {
-        for( channelIndex=0; channelIndex<data->numChannels; channelIndex++ )
-        {
-            /* Output sine wave on every channel. */
-            *out++ = (float) ( data->amplitude * sin(data->phases[channelIndex]) );
-
-            /* Play each channel at a higher frequency. */
-            data->phases[channelIndex] += FREQ_INCR * (4 + channelIndex);
-            if( data->phases[channelIndex] >= (2.0 * M_PI) ) data->phases[channelIndex] -= (2.0 * M_PI);
-        }
-    }
-
-    return 0;
-}
-/*******************************************************************/
-int main(void);
-int main(void)
-{
-    char  pad[256];
-    PortAudioStream *stream;
-    PaError err;
-    const PaDeviceInfo *pdi;
-    paTestData data = {0};
-    printf("PortAudio Test: output sine wave on each channel.\n" );
-
-    err = Pa_Initialize();
-    if( err != paNoError ) goto error;
-
-    pdi = Pa_GetDeviceInfo( OUTPUT_DEVICE );
-    data.numChannels = pdi->maxOutputChannels;
-    if( data.numChannels > MAX_CHANNELS ) data.numChannels = MAX_CHANNELS;
-    printf("Number of Channels = %d\n", data.numChannels );
-    data.amplitude = 1.0;
-    
-    err = Pa_OpenStream(
-              &stream,
-              paNoDevice, /* default input device */
-              0,              /* no input */
-              paFloat32,  /* 32 bit floating point input */
-              NULL,
-              OUTPUT_DEVICE,
-              data.numChannels,
-              paFloat32,  /* 32 bit floating point output */
-              NULL,
-              SAMPLE_RATE,
-              FRAMES_PER_BUFFER,  /* frames per buffer */
-              0,    /* number of buffers, if zero then use default minimum */
-              paClipOff,      /* we won't output out of range samples so don't bother clipping them */
-              patestCallback,
-              &data );
-    if( err != paNoError ) goto error;
-
-    err = Pa_StartStream( stream );
-    if( err != paNoError ) goto error;
-
-    do
-    {
-        printf("Current amplitude = %f\n", data.amplitude );
-        printf("Enter new amplitude or 'q' to quit.\n");
-        fflush(stdout);
-        gets( pad );
-        if( pad[0] != 'q' )
-        {
-        // I tried to use atof but it seems to be broken on Mac OS X 10.1
-            float amp;
-            sscanf( pad, "%f", &amp );
-            data.amplitude = amp;
-        }
-    } while( pad[0] != 'q' );
-
-    err = Pa_StopStream( stream );
-    if( err != paNoError ) goto error;
-
-    Pa_CloseStream( stream );
-    Pa_Terminate();
-    printf("Test finished.\n");
-    return err;
-error:
-    Pa_Terminate();
-    fprintf( stderr, "An error occured while using the portaudio stream\n" );
-    fprintf( stderr, "Error number: %d\n", err );
-    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
-    return err;
-}
diff --git a/pa_tests/debug_sine_formats.c b/pa_tests/debug_sine_formats.c
deleted file mode 100644 (file)
index a1fce56..0000000
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * $Id$
- * patest_sine_formats.c
- * Play a sine wave using the Portable Audio api for several seconds.
- * Test various data formats.
- *
- * Author: Phil Burk
- *
- * 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 <math.h>
-#include "portaudio.h"
-
-#define NUM_SECONDS        (10)
-#define SAMPLE_RATE        (44100)
-#define FRAMES_PER_BUFFER  (256)
-
-#define LEFT_FREQ          (SAMPLE_RATE/512.0)  /* So we hit 1.0 */
-#define RIGHT_FREQ         (500.0)
-
-#define AMPLITUDE          (1.0)
-
-/* Select ONE format for testing. */
-#define TEST_UINT8    (1)
-#define TEST_INT8     (0)
-#define TEST_INT16    (0)
-#define TEST_FLOAT32  (0)
-
-#if TEST_UINT8
-#define TEST_FORMAT         paUInt8
-typedef unsigned char       SAMPLE_t;
-#define SAMPLE_ZERO         (0x80)
-#define DOUBLE_TO_SAMPLE(x) (SAMPLE_ZERO + (SAMPLE_t)(127.0 * (x)))
-#define FORMAT_NAME         "Unsigned 8 Bit"
-
-#elif TEST_INT8
-#define TEST_FORMAT         paInt8
-typedef char                SAMPLE_t;
-#define SAMPLE_ZERO         (0)
-#define DOUBLE_TO_SAMPLE(x) (SAMPLE_ZERO + (SAMPLE_t)(127.0 * (x)))
-#define FORMAT_NAME         "Signed 8 Bit"
-
-#elif TEST_INT16
-#define TEST_FORMAT         paInt16
-typedef short               SAMPLE_t;
-#define SAMPLE_ZERO         (0)
-#define DOUBLE_TO_SAMPLE(x) (SAMPLE_ZERO + (SAMPLE_t)(32767 * (x)))
-#define FORMAT_NAME         "Signed 16 Bit"
-
-#elif TEST_FLOAT32
-#define TEST_FORMAT         paFloat32
-typedef float               SAMPLE_t;
-#define SAMPLE_ZERO         (0.0)
-#define DOUBLE_TO_SAMPLE(x) ((SAMPLE_t)(x))
-#define FORMAT_NAME         "Float 32 Bit"
-#endif
-
-#ifndef M_PI
-#define M_PI  (3.14159265)
-#endif
-
-
-typedef struct
-{
-    double left_phase;
-    double right_phase;
-    unsigned int framesToGo;
-}
-paTestData;
-/* This routine will be called by the PortAudio engine when audio is needed.
-** It may called at interrupt level on some machines so don't do anything
-** that could mess up the system like calling malloc() or free().
-*/
-static int patestCallback( void *inputBuffer, void *outputBuffer,
-                           unsigned long framesPerBuffer,
-                           PaTimestamp outTime, void *userData )
-{
-    paTestData *data = (paTestData*)userData;
-    SAMPLE_t *out = (SAMPLE_t *)outputBuffer;
-    SAMPLE_t sample;
-    int i;
-    int framesToCalc;
-    int finished = 0;
-    (void) outTime; /* Prevent unused variable warnings. */
-    (void) inputBuffer;
-
-    if( data->framesToGo < framesPerBuffer )
-    {
-        framesToCalc = data->framesToGo;
-        data->framesToGo = 0;
-        finished = 1;
-    }
-    else
-    {
-        framesToCalc = framesPerBuffer;
-        data->framesToGo -= framesPerBuffer;
-    }
-
-    for( i=0; i<framesToCalc; i++ )
-    {
-        data->left_phase += (LEFT_FREQ / SAMPLE_RATE);
-        if( data->left_phase > 1.0) data->left_phase -= 1.0;
-        sample = DOUBLE_TO_SAMPLE( AMPLITUDE * sin( (data->left_phase * M_PI * 2. ))); /**/
-        *out++ = sample;
-/*        *out++ = sample; /**/
-/*        *out++ = 0;  /**/
-
-        data->right_phase += (RIGHT_FREQ / SAMPLE_RATE);
-        if( data->right_phase > 1.0) data->right_phase -= 1.0;
-        *out++ = DOUBLE_TO_SAMPLE( AMPLITUDE * sin( (data->right_phase * M_PI * 2. ))); /**/
-/*        *out++ = 0;  /* */
-    }
-    /* zero remainder of final buffer */
-    for( ; i<(int)framesPerBuffer; i++ )
-    {
-        *out++ = SAMPLE_ZERO; /* left */
-        *out++ = SAMPLE_ZERO; /* right */
-    }
-    return finished;
-}
-/*******************************************************************/
-int main(void);
-int main(void)
-{
-    PortAudioStream *stream;
-    PaError err;
-    paTestData data;
-    int totalSamps;
-
-    printf("PortAudio Test: output " FORMAT_NAME "\n");
-
-
-    data.left_phase = data.right_phase = 0.0;
-    data.framesToGo = totalSamps =  NUM_SECONDS * SAMPLE_RATE; /* Play for a few seconds. */
-    err = Pa_Initialize();
-    if( err != paNoError ) goto error;
-
-    err = Pa_OpenStream(
-              &stream,
-              paNoDevice,/* default input device */
-              0,              /* no input */
-              TEST_FORMAT,
-              NULL,
-              Pa_GetDefaultOutputDeviceID(), /* default output device */
-              2,          /* stereo output */
-              TEST_FORMAT,
-              NULL,
-              SAMPLE_RATE,
-              FRAMES_PER_BUFFER,
-              0,              /* number of buffers, if zero then use default minimum */
-              paClipOff,      /* we won't output out of range samples so don't bother clipping them */
-              patestCallback,
-              &data );
-    if( err != paNoError ) goto error;
-
-    err = Pa_StartStream( stream );
-    if( err != paNoError ) goto error;
-
-    printf("Waiting %d seconds for sound to finish.\n", NUM_SECONDS );
-    while( Pa_StreamActive( stream ) ) Pa_Sleep(10);
-
-    err = Pa_CloseStream( stream );
-    if( err != paNoError ) goto error;
-    Pa_Terminate();
-
-    printf("PortAudio Test Finished: " FORMAT_NAME "\n");
-
-    return err;
-error:
-    Pa_Terminate();
-    fprintf( stderr, "An error occured while using the portaudio stream\n" );
-    fprintf( stderr, "Error number: %d\n", err );
-    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
-    return err;
-}
similarity index 76%
rename from pa_tests/patest_hang.c
rename to pa_tests/debug_sine_wait.c
index 6d533dabb1d1b8904348e7558d472f18f736aae5..863ae778601522e3faf78a6f8b5cf3936ae7b4a2 100644 (file)
@@ -1,6 +1,7 @@
 /*
  * $Id$
- * Play a sine then hang audio callback to test watchdog.
+ * debug_sine_wait.c
+ * Play a sine wave using the Portable Audio api until we hit ENTER.
  *
  * Authors:
  *    Ross Bencina <rossb@audiomulch.com>
 #include <math.h>
 #include "portaudio.h"
 
-
+#define NUM_SECONDS   (20)
 #define SAMPLE_RATE   (44100)
-#define FRAMES_PER_BUFFER  (1024)
+#define FRAMES_PER_BUFFER  (64)
+#define NUM_BUFFERS   (16)
+
 #ifndef M_PI
 #define M_PI  (3.14159265)
 #endif
-#define TWOPI (M_PI * 2.0)
 
-typedef struct paTestData
+#define TABLE_SIZE   (200)
+typedef struct
 {
-    int    sleepFor;
-    double phase;
+    float sine[TABLE_SIZE];
+    int left_phase;
+    int right_phase;
 }
 paTestData;
 
@@ -65,26 +69,17 @@ static int patestCallback(   void *inputBuffer, void *outputBuffer,
     float *out = (float*)outputBuffer;
     unsigned long i;
     int finished = 0;
-    double phaseInc = 0.02;
-    double phase = data->phase;
-    
     (void) outTime; /* Prevent unused variable warnings. */
     (void) inputBuffer;
-
     for( i=0; i<framesPerBuffer; i++ )
     {
-        phase += phaseInc;
-        if( phase > TWOPI ) phase -= TWOPI;
-        /* This is not a very efficient way to calc sines. */
-        *out++ = (float) sin( phase ); /* mono */
-    }
-    
-    if( data->sleepFor > 0 )
-    {
-        Pa_Sleep( data->sleepFor );
+        *out++ = data->sine[data->left_phase];  /* left */
+        *out++ = data->sine[data->right_phase];  /* right */
+        data->left_phase += 1;
+        if( data->left_phase >= TABLE_SIZE ) data->left_phase -= TABLE_SIZE;
+        data->right_phase += 3; /* higher pitch so we can distinguish left and right. */
+        if( data->right_phase >= TABLE_SIZE ) data->right_phase -= TABLE_SIZE;
     }
-    
-    data->phase = phase;
     return finished;
 }
 
@@ -93,16 +88,18 @@ int main(void);
 int main(void)
 {
     PortAudioStream *stream;
-    PaError          err;
-    int              i;
-    paTestData       data = {0};
-    
-    printf("PortAudio Test: output sine wave. SR = %d, BufSize = %d\n",
-        SAMPLE_RATE, FRAMES_PER_BUFFER );
-
+    PaError err;
+    paTestData data;
+    int i;
+    printf("PortAudio Test: output sine wave. SR = %d, BufSize = %d\n", SAMPLE_RATE, FRAMES_PER_BUFFER);
+    /* initialise sinusoidal wavetable */
+    for( i=0; i<TABLE_SIZE; i++ )
+    {
+        data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
+    }
+    data.left_phase = data.right_phase = 0;
     err = Pa_Initialize();
     if( err != paNoError ) goto error;
-    
     err = Pa_OpenStream(
               &stream,
               paNoDevice,/* default input device */
@@ -110,31 +107,21 @@ int main(void)
               paFloat32,  /* 32 bit floating point input */
               NULL,
               Pa_GetDefaultOutputDeviceID(), /* default output device */
-              1,          /* mono output */
+              2,          /* stereo output */
               paFloat32,      /* 32 bit floating point output */
               NULL,
               SAMPLE_RATE,
-              FRAMES_PER_BUFFER,            /* frames per buffer */
-              0,              /* number of buffers, if zero then use default minimum */
+              FRAMES_PER_BUFFER,
+              NUM_BUFFERS,    /* number of buffers, if zero then use default minimum */
               paClipOff,      /* we won't output out of range samples so don't bother clipping them */
               patestCallback,
               &data );
     if( err != paNoError ) goto error;
-    
     err = Pa_StartStream( stream );
     if( err != paNoError ) goto error;
+    printf("Hit ENTER to stop.\n");
+    gets(stdin);
 
-/* Gradually increase sleep time. */
-    for( i=0; i<10000; i+= 1000 )
-    {
-        printf("Sleep for %d milliseconds in audio callback.\n", i );
-        data.sleepFor = i;
-        Pa_Sleep( ((i<1000) ? 1000 : i) );
-    }
-    
-    printf("Suffer for 10 seconds.\n");
-    Pa_Sleep( 10000 );
-    
     err = Pa_StopStream( stream );
     if( err != paNoError ) goto error;
     err = Pa_CloseStream( stream );
diff --git a/pa_tests/debug_srate.c b/pa_tests/debug_srate.c
deleted file mode 100644 (file)
index 07371f2..0000000
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
- * $Id$
- * debug_record_reuse.c
- * Record input into an array.
- * Save array to a file.
- * Based on patest_record.c but with various ugly debug hacks thrown in.
- * Loop twice and reuse same streams.
- *
- * Author: Phil Burk  http://www.softsynth.com
- *
- * This program uses the PortAudio Portable Audio Library.
- * For more information see: http://www.portaudio.com
- * 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 <memory.h>
-#include "portaudio.h"
-
-#define EWS88MT_12_REC     (1)
-#define EWS88MT_12_PLAY   (10)
-#define SBLIVE_REC         (2)
-#define SBLIVE_PLAY       (11)
-
-#if 0
-#define INPUT_DEVICE_ID    Pa_GetDefaultInputDeviceID()
-#define OUTPUT_DEVICE_ID   Pa_GetDefaultOutputDeviceID()
-#else
-#define INPUT_DEVICE_ID    (EWS88MT_12_REC)
-#define OUTPUT_DEVICE_ID   (SBLIVE_PLAY)
-#endif
-
-#define INPUT_SAMPLE_RATE     (22050.0)
-#define OUTPUT_SAMPLE_RATE    (22050.0)
-#define NUM_SECONDS               (4)
-#define SLEEP_DUR_MSEC         (1000)
-#define FRAMES_PER_BUFFER        (64)
-#define NUM_REC_BUFS              (0)
-#define SAMPLES_PER_FRAME         (2)
-
-#define PA_SAMPLE_TYPE  paInt16
-typedef short SAMPLE;
-
-typedef struct
-{
-    long             frameIndex;  /* Index into sample array. */
-}
-paTestData;
-
-/* This routine will be called by the PortAudio engine when audio is needed.
-** It may be called at interrupt level on some machines so don't do anything
-** that could mess up the system like calling malloc() or free().
-*/
-static int recordCallback( void *inputBuffer, void *outputBuffer,
-                           unsigned long framesPerBuffer,
-                           PaTimestamp outTime, void *userData )
-{
-    paTestData *data = (paTestData *) userData;
-    (void) outputBuffer; /* Prevent unused variable warnings. */
-    (void) outTime;
-
-    if( inputBuffer != NULL )
-    {
-        data->frameIndex += framesPerBuffer;
-    }
-    return 0;
-}
-
-/* This routine will be called by the PortAudio engine when audio is needed.
-** It may be called at interrupt level on some machines so don't do anything
-** that could mess up the system like calling malloc() or free().
-*/
-static int playCallback( void *inputBuffer, void *outputBuffer,
-                         unsigned long framesPerBuffer,
-                         PaTimestamp outTime, void *userData )
-{
-    paTestData *data = (paTestData *) userData;
-    (void) inputBuffer; /* Prevent unused variable warnings. */
-    (void) outTime;
-
-    if( outputBuffer != NULL )
-    {
-        data->frameIndex += framesPerBuffer;
-    }
-    return 0;
-}
-
-/****************************************************************/
-PaError MeasureStreamRate( PortAudioStream *stream, paTestData *dataPtr, double *ratePtr )
-{
-    PaError    err;
-    int        i;
-    int        totalFrames = 0;
-    int        totalMSec = 0;
-
-    dataPtr->frameIndex = 0;
-
-    err = Pa_StartStream( stream );
-    if( err != paNoError ) goto error;
-
-    for( i=0; i<(NUM_SECONDS*1000/SLEEP_DUR_MSEC); i++ )
-    {
-        int delta, endIndex;
-
-        int startIndex = dataPtr->frameIndex;
-        Pa_Sleep(SLEEP_DUR_MSEC);
-        endIndex = dataPtr->frameIndex;
-
-        delta = endIndex - startIndex;
-        totalFrames += delta;
-        totalMSec += SLEEP_DUR_MSEC;
-
-        printf("index = %d, delta = %d\n", endIndex, delta ); fflush(stdout);
-    }
-
-    err = Pa_StopStream( stream );
-    if( err != paNoError ) goto error;
-
-    *ratePtr = (totalFrames * 1000.0) / totalMSec;
-
-error:
-    return err;
-}
-
-void ReportRate( double measuredRate, double expectedRate )
-{
-    double error;
-
-    error = (measuredRate - expectedRate) / expectedRate;
-    error = (error < 0 ) ? -error : error;
-
-    printf("Measured rate = %6.1f, expected rate = %6.1f\n",
-            measuredRate, expectedRate );
-    if( error > 0.1 )
-    {
-        printf("ERROR: unexpected rate! ---------------------   ERROR!\n");
-    }
-    else
-    {
-        printf("SUCCESS: rate within tolerance!\n");
-    }
-}
-
-/*******************************************************************/
-int main(void);
-int main(void)
-{
-    PaError    err;
-    paTestData data = { 0 };
-    long       i;
-    double     rate;
-    const    PaDeviceInfo *pdi;
-
-    PortAudioStream *outputStream;
-    PortAudioStream *inputStream;
-
-    err = Pa_Initialize();
-    if( err != paNoError ) goto error;
-
-
-    pdi = Pa_GetDeviceInfo( INPUT_DEVICE_ID );
-    printf("Input device  = %s\n", pdi->name );
-    pdi = Pa_GetDeviceInfo( OUTPUT_DEVICE_ID );
-    printf("Output device = %s\n", pdi->name );
-
-/* Open input stream. */
-    err = Pa_OpenStream(
-              &inputStream,
-              INPUT_DEVICE_ID,
-              SAMPLES_PER_FRAME,               /* stereo input */
-              PA_SAMPLE_TYPE,
-              NULL,
-              paNoDevice,
-              0,
-              PA_SAMPLE_TYPE,
-              NULL,
-              INPUT_SAMPLE_RATE,
-              FRAMES_PER_BUFFER,            /* frames per buffer */
-              NUM_REC_BUFS,               /* number of buffers, if zero then use default minimum */
-              paClipOff,       /* we won't output out of range samples so don't bother clipping them */
-              recordCallback,
-              &data );
-    if( err != paNoError ) goto error;
-
-    err = Pa_OpenStream(
-              &outputStream,
-              paNoDevice,
-              0,               /* NO input */
-              PA_SAMPLE_TYPE,
-              NULL,
-              OUTPUT_DEVICE_ID,
-              SAMPLES_PER_FRAME,               /* stereo output */
-              PA_SAMPLE_TYPE,
-              NULL,
-              OUTPUT_SAMPLE_RATE,
-              FRAMES_PER_BUFFER,            /* frames per buffer */
-              0,               /* number of buffers, if zero then use default minimum */
-              paClipOff,       /* we won't output out of range samples so don't bother clipping them */
-              playCallback,
-              &data );
-    if( err != paNoError ) goto error;
-
-/* Record and playback multiple times. */
-    for( i=0; i<2; i++ )
-    {
-        printf("Measuring INPUT ------------------------- \n");
-        err = MeasureStreamRate( inputStream, &data, &rate );
-        if( err != paNoError ) goto error;
-        ReportRate( rate, INPUT_SAMPLE_RATE );
-
-        printf("Measuring OUTPUT ------------------------- \n");
-        err = MeasureStreamRate( outputStream, &data, &rate );
-        if( err != paNoError ) goto error;
-        ReportRate( rate, OUTPUT_SAMPLE_RATE );
-    }
-
-/* Clean up. */
-    err = Pa_CloseStream( inputStream );
-    if( err != paNoError ) goto error;
-
-    err = Pa_CloseStream( outputStream );
-    if( err != paNoError ) goto error;
-
-    if( err != paNoError ) goto error;
-
-    Pa_Terminate();
-    
-    printf("Test complete.\n"); fflush(stdout);
-    return 0;
-
-error:
-    Pa_Terminate();
-    fprintf( stderr, "An error occured while using the portaudio stream\n" );
-    fprintf( stderr, "Error number: %d\n", err );
-    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
-    if( err == paHostError )
-    {
-        fprintf( stderr, "Host Error number: %d\n", Pa_GetHostError() );
-    }
-    return -1;
-}
index 90b20df7448a6f32d71ee3ba5d76215c8c4d67b0..356ccb9c8a1a71363db9d5acb6de55eceaa2ac20 100644 (file)
 #include <stdlib.h>
 #include <math.h>
 #include "portaudio.h"
-
 #ifndef M_PI
 #define M_PI  (3.14159265)
 #endif
-#define TWOPI (M_PI * 2.0)
-
-#define DEFAULT_BUFFER_SIZE   (64)
-
+#define DEFAULT_BUFFER_SIZE   (128)
+#define TABLE_SIZE   (200)
 typedef struct
 {
-    double left_phase;
-    double right_phase;
+    float sine[TABLE_SIZE];
+    int left_phase;
+    int right_phase;
 }
 paTestData;
-
 /* Very simple synthesis routine to generate two sine waves. */
 static int paminlatCallback( void *inputBuffer, void *outputBuffer,
                              unsigned long framesPerBuffer,
@@ -61,25 +58,15 @@ static int paminlatCallback( void *inputBuffer, void *outputBuffer,
     paTestData *data = (paTestData*)userData;
     float *out = (float*)outputBuffer;
     unsigned int i;
-    double left_phaseInc = 0.02;
-    double right_phaseInc = 0.06;
-
-    double left_phase = data->left_phase;
-    double right_phase = data->right_phase;
-
     for( i=0; i<framesPerBuffer; i++ )
     {
-        left_phase += left_phaseInc;
-        if( left_phase > TWOPI ) left_phase -= TWOPI;
-        *out++ = (float) sin( left_phase );
-
-        right_phase += right_phaseInc;
-        if( right_phase > TWOPI ) right_phase -= TWOPI;
-        *out++ = (float) sin( right_phase );
+        *out++ = data->sine[data->left_phase];  /* left */
+        *out++ = data->sine[data->right_phase];  /* right */
+        data->left_phase += 1;
+        if( data->left_phase >= TABLE_SIZE ) data->left_phase -= TABLE_SIZE;
+        data->right_phase += 3; /* higher pitch so we can distinguish left and right. */
+        if( data->right_phase >= TABLE_SIZE ) data->right_phase -= TABLE_SIZE;
     }
-
-    data->left_phase = left_phase;
-    data->right_phase = right_phase;
     return 0;
 }
 void main( int argc, char **argv );
@@ -88,6 +75,7 @@ void main( int argc, char **argv )
     PortAudioStream *stream;
     PaError err;
     paTestData data;
+    int    i;
     int    go;
     int    numBuffers = 0;
     int    minBuffers = 0;
@@ -103,8 +91,12 @@ void main( int argc, char **argv )
     /* Get bufferSize from command line. */
     framesPerBuffer = ( argc > 1 ) ? atol( argv[1] ) : DEFAULT_BUFFER_SIZE;
     printf("Frames per buffer = %d\n", framesPerBuffer );
-
-    data.left_phase = data.right_phase = 0.0;
+    /* Initialise sinusoidal wavetable. */
+    for( i=0; i<TABLE_SIZE; i++ )
+    {
+        data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
+    }
+    data.left_phase = data.right_phase = 0;
     err = Pa_Initialize();
     if( err != paNoError ) goto error;
     /* Ask PortAudio for the recommended minimum number of buffers. */
@@ -129,7 +121,7 @@ void main( int argc, char **argv )
                   paFloat32,      /* 32 bit floating point output */
                   NULL,
                   sampleRate,
-                  framesPerBuffer,
+                  framesPerBuffer,/* 46 msec buffers */
                   numBuffers,     /* number of buffers */
                   paClipOff,      /* we won't output out of range samples so don't bother clipping them */
                   paminlatCallback,
index e5ffc6281659d46656a5e4df6d3cdf920c395ce0..37e75d7c14e9e3bfe1baf84800a371540449c065 100644 (file)
@@ -270,31 +270,6 @@ static int TestBadOpens( void )
                                QaCallback,
                                &myData )
                  ) == paInvalidFlag) );
-
-#if 0 /* FIXME - this is legal for some implementations. */
-    HOPEFOR( ( /* Use input device as output device. */
-                 (result = Pa_OpenStream(
-                               &stream,
-                               paNoDevice, 0, paFloat32, NULL,
-                               Pa_GetDefaultInputDeviceID(), 2, paFloat32, NULL,
-                               SAMPLE_RATE, FRAMES_PER_BUFFER, NUM_BUFFERS,
-                               paClipOff,
-                               QaCallback,
-                               &myData )
-                 ) == paInvalidDeviceId) );
-
-    HOPEFOR( ( /* Use output device as input device. */
-                 (result = Pa_OpenStream(
-                               &stream,
-                               Pa_GetDefaultOutputDeviceID(), 2, paFloat32, NULL,
-                               paNoDevice, 0, paFloat32, NULL,
-                               SAMPLE_RATE, FRAMES_PER_BUFFER, NUM_BUFFERS,
-                               paClipOff,
-                               QaCallback,
-                               &myData )
-                 ) == paInvalidDeviceId) );
-#endif
-
     if( stream != NULL ) Pa_CloseStream( stream );
     return result;
 }
index 1aa0d38fc2da6b534cb89d614da4a7af14354f81..88781611eb60de9561c3bd8d9715b204d4fa3d66 100644 (file)
@@ -2,7 +2,6 @@
  * $Id$
  * patest_dither.c
  * Attempt to hear difference between dithered and non-dithered signal.
- * This only has an effect if the native format is 16 bit.
  *
  * Author: Phil Burk  http://www.softsynth.com
  *
index 30c8160d19047585887d1fb829f87cb6853ed1ac..2daf431e2416e1320e9d07bd4b4bf6da2af9a673 100644 (file)
@@ -1,9 +1,9 @@
 /*
  * $Id$
- * Hear the latency caused by big buffers.
+ * Hear the latency caused by bug buffers.
  * Play a sine wave and change frequency based on letter input.
  *
- * Author: Phil Burk <philburk@softsynth.com>, and Darren Gibbs
+ * Author: Phil Burk <philburk@softsynth.com>
  *
  * This program uses the PortAudio Portable Audio Library.
  * For more information see: http://www.portaudio.com
 #include <stdio.h>
 #include <math.h>
 #include "portaudio.h"
-
 #define OUTPUT_DEVICE       (Pa_GetDefaultOutputDeviceID())
 #define SAMPLE_RATE         (44100)
-#define FRAMES_PER_BUFFER   (64)
-
-#if 0
+#define FRAMES_PER_BUFFER   (256)
+#if 1
 #define MIN_LATENCY_MSEC    (2000)
 #define NUM_BUFFERS         ((MIN_LATENCY_MSEC * SAMPLE_RATE) / (FRAMES_PER_BUFFER * 1000))
 #else
 #define NUM_BUFFERS         (0)
 #endif
-
 #define MIN_FREQ            (100.0f)
 #define CalcPhaseIncrement(freq)  ((freq)/SAMPLE_RATE)
 #ifndef M_PI
@@ -56,7 +53,7 @@
 #define TABLE_SIZE   (400)
 typedef struct
 {
-    float sine[TABLE_SIZE + 1]; /* add one for guard point for interpolation */
+    float sine[TABLE_SIZE + 1]; // add one for guard point for interpolation
     float phase_increment;
     float left_phase;
     float right_phase;
@@ -111,16 +108,15 @@ int main(void)
     paTestData data;
     int i;
     int done = 0;
-    printf("PortAudio Test: enter letter then hit ENTER. numBuffers = %d\n", NUM_BUFFERS );
+    printf("PortAudio Test: output sine sweep. ask for %d buffers\n", NUM_BUFFERS );
     /* initialise sinusoidal wavetable */
     for( i=0; i<TABLE_SIZE; i++ )
     {
-        data.sine[i] = 0.90f * (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
+        data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
     }
-    data.sine[TABLE_SIZE] = data.sine[0];       /* set guard point */
+    data.sine[TABLE_SIZE] = data.sine[0]; // set guard point
     data.left_phase = data.right_phase = 0.0;
     data.phase_increment = CalcPhaseIncrement(MIN_FREQ);
-
     err = Pa_Initialize();
     if( err != paNoError ) goto error;
     printf("PortAudio Test: output device = %d\n", OUTPUT_DEVICE );
@@ -144,7 +140,6 @@ int main(void)
     err = Pa_StartStream( stream );
     if( err != paNoError ) goto error;
     printf("Play ASCII keyboard. Hit 'q' to stop. (Use RETURN key on Mac)\n");
-    fflush(stdout);
     while ( !done )
     {
         float  freq;
index d718aef5c1ab94790bb6eda45926addfbf0642da..7e19b17a4b1206cc2fd7bc69c4e39f116c013f2c 100644 (file)
@@ -98,7 +98,6 @@ static int patestCallback(   void *inputBuffer, void *outputBuffer,
 
     return finished;
 }
-
 /*******************************************************************/
 int main(void);
 int main(void)
@@ -108,21 +107,17 @@ int main(void)
     paTestData data;
     int i;
     int timeout;
-    
-    printf("Play different tone sine waves that alternate between left and right channel.\n");
-    printf("The low tone should be on the left channel.\n");
-    
+    printf("PortAudio Test: output sine wave. SR = %d, BufSize = %d\n", SAMPLE_RATE, FRAMES_PER_BUFFER);
     /* initialise sinusoidal wavetable */
     for( i=0; i<TABLE_SIZE; i++ )
     {
         data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
     }
-    data.left_phase = data.right_phase = data.toggle = 0;
+    data.left_phase = data.right_phase = 0;
     data.countDown = SAMPLE_RATE;
 
     err = Pa_Initialize();
     if( err != paNoError ) goto error;
-    
     err = Pa_OpenStream(
               &stream,
               paNoDevice,/* default input device */
@@ -140,15 +135,15 @@ int main(void)
               patestCallback,
               &data );
     if( err != paNoError ) goto error;
-    
     err = Pa_StartStream( stream );
     if( err != paNoError ) goto error;
-    
     printf("Play for several seconds.\n");
     timeout = NUM_SECONDS * 4;
     while( timeout > 0 )
     {
-        Pa_Sleep( 300 );
+        printf("Countdown = %d, Toggle = %d\n", data.countDown, data.toggle );
+        fflush( stdout );
+        Pa_Sleep( 1000/4 );
         timeout -= 1;
     }
 
index 0e1e337de3ccd81a8d79efdf3423122a7150be3a..3d8bd4cba6289c06217578acbe232cbf74b492cd 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * $Id$
  * patest_longsine.c
- * Play a sine wave using the Portable Audio api until ENTER hit.
+ * Play a sine wave using the Portable Audio api forever.
  *
  * Author: Phil Burk  http://www.softsynth.com
  *
 #include <stdio.h>
 #include <math.h>
 #include "portaudio.h"
-
 #define SAMPLE_RATE   (44100)
-
 #ifndef M_PI
 #define M_PI  (3.14159265)
 #endif
-
 #define TABLE_SIZE   (200)
 typedef struct
 {
@@ -51,7 +48,6 @@ typedef struct
     int right_phase;
 }
 paTestData;
-
 /* This routine will be called by the PortAudio engine when audio is needed.
 ** It may called at interrupt level on some machines so don't do anything
 ** that could mess up the system like calling malloc() or free().
@@ -76,7 +72,6 @@ static int patestCallback( void *inputBuffer, void *outputBuffer,
     }
     return 0;
 }
-
 /*******************************************************************/
 int main(void);
 int main(void)
@@ -86,17 +81,14 @@ int main(void)
     paTestData data;
     int i;
     printf("PortAudio Test: output sine wave.\n");
-
     /* initialise sinusoidal wavetable */
     for( i=0; i<TABLE_SIZE; i++ )
     {
         data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
     }
     data.left_phase = data.right_phase = 0;
-
     err = Pa_Initialize();
     if( err != paNoError ) goto error;
-
     err = Pa_OpenStream(
               &stream,
               paNoDevice,/* default input device */
@@ -114,20 +106,15 @@ int main(void)
               patestCallback,
               &data );
     if( err != paNoError ) goto error;
-
     err = Pa_StartStream( stream );
     if( err != paNoError ) goto error;
-
     printf("Hit ENTER to stop program.\n");
     getchar();
-
     err = Pa_CloseStream( stream );
     if( err != paNoError ) goto error;
     Pa_Terminate();
-
     printf("Test finished.\n");
     return err;
-
 error:
     Pa_Terminate();
     fprintf( stderr, "An error occured while using the portaudio stream\n" );
index 7745be84bc4c1aa332eafc509181fb917c152f05..deae6c6759977ac813f19dcd9eca058994802568 100644 (file)
 #include "portaudio.h"
 
 #define MAX_SINES     (500)
-#define MAX_USAGE     (0.8)
 #define SAMPLE_RATE   (44100)
-#define FREQ_TO_PHASE_INC(freq)   (freq/(float)SAMPLE_RATE)
-
-#define MIN_PHASE_INC  FREQ_TO_PHASE_INC(200.0f)
-#define MAX_PHASE_INC  (MIN_PHASE_INC * (1 << 5))
-
 #define FRAMES_PER_BUFFER  (512)
 #ifndef M_PI
 #define M_PI  (3.14159265)
 #endif
 #define TWOPI (M_PI * 2.0)
 
-#define TABLE_SIZE   (512)
-
 typedef struct paTestData
 {
     int numSines;
-    float sine[TABLE_SIZE + 1]; /* add one for guard point for interpolation */
-    float phases[MAX_SINES];
+    double phases[MAX_SINES];
 }
 paTestData;
 
-/* Convert phase between and 1.0 to sine value
- * using linear interpolation.
- */
-float LookupSine( paTestData *data, float phase );
-float LookupSine( paTestData *data, float phase )
-{
-    float fIndex = phase*TABLE_SIZE;
-    int   index = (int) fIndex;
-    float fract = fIndex - index;
-    float lo = data->sine[index];
-    float hi = data->sine[index+1];
-    float val = lo + fract*(hi-lo);
-    return val;
-}
-
 /* This routine will be called by the PortAudio engine when audio is needed.
 ** It may called at interrupt level on some machines so don't do anything
 ** that could mess up the system like calling malloc() or free().
@@ -88,42 +64,34 @@ static int patestCallback(   void *inputBuffer, void *outputBuffer,
 {
     paTestData *data = (paTestData*)userData;
     float *out = (float*)outputBuffer;
-    float outSample;
-    float scaler;
-    int numForScale;
     unsigned long i;
     int j;
     int finished = 0;
     (void) outTime; /* Prevent unused variable warnings. */
     (void) inputBuffer;
 
-/* Detemine amplitude scaling factor */
-    numForScale = data->numSines;
-    if( numForScale < 8 ) numForScale = 8;  /* prevent pops at beginning */
-    scaler = 1.0f / numForScale;
-    
     for( i=0; i<framesPerBuffer; i++ )
     {
         float output = 0.0;
-        float phaseInc = MIN_PHASE_INC;
-        float phase;
+        double phaseInc = 0.02;
+        double phase;
         for( j=0; j<data->numSines; j++ )
         {
             /* Advance phase of next oscillator. */
             phase = data->phases[j];
             phase += phaseInc;
-            if( phase >= 1.0 ) phase -= 1.0;
+            if( phase > TWOPI ) phase -= TWOPI;
+
+            phaseInc *= 1.02;
+            if( phaseInc > 0.5 ) phaseInc *= 0.5;
 
-            output += LookupSine(data, phase); 
+            /* This is not a very efficient way to calc sines. */
+            output += (float) sin( phase );
             data->phases[j] = phase;
-            
-            phaseInc *= 1.02f;
-            if( phaseInc > MAX_PHASE_INC ) phaseInc = MIN_PHASE_INC;
         }
 
-        outSample = (float) (output * scaler);
-        *out++ = outSample; /* Left */
-        *out++ = outSample; /* Right */
+
+        *out++ = (float) (output / data->numSines);
     }
     return finished;
 }
@@ -132,34 +100,27 @@ static int patestCallback(   void *inputBuffer, void *outputBuffer,
 int main(void);
 int main(void)
 {
-       int i;
     PortAudioStream *stream;
     PaError err;
     paTestData data = {0};
     double load;
     printf("PortAudio Test: output sine wave. SR = %d, BufSize = %d\n", SAMPLE_RATE, FRAMES_PER_BUFFER);
-
     /* initialise sinusoidal wavetable */
-    for( i=0; i<TABLE_SIZE; i++ )
-    {
-        data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
-    }
-    data.sine[TABLE_SIZE] = data.sine[0]; /* set guard point */
 
     err = Pa_Initialize();
     if( err != paNoError ) goto error;
     err = Pa_OpenStream(
               &stream,
-              paNoDevice,
+              paNoDevice,/* default input device */
               0,              /* no input */
-              paFloat32,
+              paFloat32,  /* 32 bit floating point input */
               NULL,
               Pa_GetDefaultOutputDeviceID(), /* default output device */
-              2,              /* stereo output */
+              1,          /* mono output */
               paFloat32,      /* 32 bit floating point output */
               NULL,
               SAMPLE_RATE,
-              FRAMES_PER_BUFFER, 
+              FRAMES_PER_BUFFER,            /* frames per buffer */
               0,              /* number of buffers, if zero then use default minimum */
               paClipOff,      /* we won't output out of range samples so don't bother clipping them */
               patestCallback,
@@ -168,7 +129,6 @@ int main(void)
     err = Pa_StartStream( stream );
     if( err != paNoError ) goto error;
 
-/* Play an increasing number of sine waves until we hit MAX_USAGE */
     do
     {
         data.numSines++;
@@ -176,9 +136,8 @@ int main(void)
 
         load = Pa_GetCPULoad( stream );
         printf("numSines = %d, CPU load = %f\n", data.numSines, load );
-        fflush( stdout );
     }
-    while( (load < MAX_USAGE) && (data.numSines < MAX_SINES) );
+    while( load < 0.8 );
 
     err = Pa_StopStream( stream );
     if( err != paNoError ) goto error;
diff --git a/pa_tests/patest_multi_sine.c b/pa_tests/patest_multi_sine.c
deleted file mode 100644 (file)
index 01ea2a1..0000000
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * $Id$
- * patest_multi_out.c
- * Play a different sine wave on each channels,
- * using the Portable Audio api.
- *
- * Author: Phil Burk  http://www.softsynth.com
- *
- * This program uses the PortAudio Portable Audio Library.
- * For more information see: http://www.portaudio.com
- * 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 <math.h>
-#include "portaudio.h"
-
-#define OUTPUT_DEVICE       (Pa_GetDefaultOutputDeviceID())
-#define SAMPLE_RATE         (44100)
-#define FRAMES_PER_BUFFER   (256)
-#define FREQ_INCR           (300.0 / SAMPLE_RATE)
-#define MAX_CHANNELS        (64)
-
-#ifndef M_PI
-#define M_PI  (3.14159265)
-#endif
-
-typedef struct
-{
-    int      numChannels;
-    double   phases[MAX_CHANNELS];
-}
-paTestData;
-
-/* This routine will be called by the PortAudio engine when audio is needed.
-** It may called at interrupt level on some machines so don't do anything
-** that could mess up the system like calling malloc() or free().
-*/
-static int patestCallback( void *inputBuffer, void *outputBuffer,
-                           unsigned long framesPerBuffer,
-                           PaTimestamp outTime, void *userData )
-{
-    paTestData *data = (paTestData*)userData;
-    float *out = (float*)outputBuffer;
-    int frameIndex, channelIndex;
-    int finished = 0;
-    (void) outTime; /* Prevent unused variable warnings. */
-    (void) inputBuffer;
-
-    for( frameIndex=0; frameIndex<(int)framesPerBuffer; frameIndex++ )
-    {
-        for( channelIndex=0; channelIndex<data->numChannels; channelIndex++ )
-        {
-            /* Output sine wave on every channel. */
-            *out++ = (float) sin(data->phases[channelIndex]);
-
-            /* Play each channel at a higher frequency. */
-            data->phases[channelIndex] += FREQ_INCR * (4 + channelIndex);
-            if( data->phases[channelIndex] >= (2.0 * M_PI) ) data->phases[channelIndex] -= (2.0 * M_PI);
-        }
-    }
-
-    return 0;
-}
-
-/*******************************************************************/
-int main(void);
-int main(void)
-{
-    PortAudioStream *stream;
-    PaError err;
-    const PaDeviceInfo *pdi;
-    paTestData data = {0};
-    printf("PortAudio Test: output sine wave on each channel.\n" );
-
-    err = Pa_Initialize();
-    if( err != paNoError ) goto error;
-
-    pdi = Pa_GetDeviceInfo( OUTPUT_DEVICE );
-    data.numChannels = pdi->maxOutputChannels;
-    if( data.numChannels > MAX_CHANNELS ) data.numChannels = MAX_CHANNELS;
-    printf("Number of Channels = %d\n", data.numChannels );
-    
-    err = Pa_OpenStream(
-              &stream,
-              paNoDevice, /* default input device */
-              0,              /* no input */
-              paFloat32,  /* 32 bit floating point input */
-              NULL,
-              OUTPUT_DEVICE,
-              data.numChannels,
-              paFloat32,  /* 32 bit floating point output */
-              NULL,
-              SAMPLE_RATE,
-              FRAMES_PER_BUFFER,  /* frames per buffer */
-              0,    /* number of buffers, if zero then use default minimum */
-              paClipOff,      /* we won't output out of range samples so don't bother clipping them */
-              patestCallback,
-              &data );
-    if( err != paNoError ) goto error;
-
-    err = Pa_StartStream( stream );
-    if( err != paNoError ) goto error;
-
-    printf("Hit ENTER to stop sound.\n");
-    getchar();
-
-    err = Pa_StopStream( stream );
-    if( err != paNoError ) goto error;
-
-    Pa_CloseStream( stream );
-    Pa_Terminate();
-    printf("Test finished.\n");
-    return err;
-error:
-    Pa_Terminate();
-    fprintf( stderr, "An error occured while using the portaudio stream\n" );
-    fprintf( stderr, "Error number: %d\n", err );
-    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
-    return err;
-}
index 11d8791e9dc29e879421c78161e347c2c744ac39..47ccec165f902ba7ded6c15c50d48fe3b2b0f3ba 100644 (file)
 /* #define SAMPLE_RATE  (17932) /* Test failure to open with this value. */
 #define SAMPLE_RATE  (44100)
 #define NUM_SECONDS     (5)
-#define NUM_CHANNELS    (2)
-/* #define DITHER_FLAG     (paDitherOff)  /**/
-#define DITHER_FLAG     (0) /**/
 
 /* Select sample format. */
 #if 0
 #define PA_SAMPLE_TYPE  paFloat32
 typedef float SAMPLE;
-#define SAMPLE_SILENCE  (0.0f)
 #elif 0
 #define PA_SAMPLE_TYPE  paInt16
 typedef short SAMPLE;
-#define SAMPLE_SILENCE  (0)
-#elif 0
-#define PA_SAMPLE_TYPE  paInt8
-typedef char SAMPLE;
-#define SAMPLE_SILENCE  (0)
 #else
 #define PA_SAMPLE_TYPE  paUInt8
 typedef unsigned char SAMPLE;
-#define SAMPLE_SILENCE  (128)
-
 #endif
 
 typedef struct
 {
     int          frameIndex;  /* Index into sample array. */
     int          maxFrameIndex;
+    int          samplesPerFrame;
     SAMPLE      *recordedSamples;
 }
 paTestData;
@@ -83,7 +73,7 @@ static int recordCallback( void *inputBuffer, void *outputBuffer,
 {
     paTestData *data = (paTestData*)userData;
     SAMPLE *rptr = (SAMPLE*)inputBuffer;
-    SAMPLE *wptr = &data->recordedSamples[data->frameIndex * NUM_CHANNELS];
+    SAMPLE *wptr = &data->recordedSamples[data->frameIndex * data->samplesPerFrame];
     long framesToCalc;
     long i;
     int finished;
@@ -106,8 +96,8 @@ static int recordCallback( void *inputBuffer, void *outputBuffer,
     {
         for( i=0; i<framesToCalc; i++ )
         {
-            *wptr++ = SAMPLE_SILENCE;  /* left */
-            if( NUM_CHANNELS == 2 ) *wptr++ = SAMPLE_SILENCE;  /* right */
+            *wptr++ = 0;  /* left */
+            *wptr++ = 0;  /* right */
         }
     }
     else
@@ -115,7 +105,7 @@ static int recordCallback( void *inputBuffer, void *outputBuffer,
         for( i=0; i<framesToCalc; i++ )
         {
             *wptr++ = *rptr++;  /* left */
-            if( NUM_CHANNELS == 2 ) *wptr++ = *rptr++;  /* right */
+            *wptr++ = *rptr++;  /* right */
         }
     }
     data->frameIndex += framesToCalc;
@@ -131,7 +121,7 @@ static int playCallback( void *inputBuffer, void *outputBuffer,
                          PaTimestamp outTime, void *userData )
 {
     paTestData *data = (paTestData*)userData;
-    SAMPLE *rptr = &data->recordedSamples[data->frameIndex * NUM_CHANNELS];
+    SAMPLE *rptr = &data->recordedSamples[data->frameIndex * data->samplesPerFrame];
     SAMPLE *wptr = (SAMPLE*)outputBuffer;
     unsigned int i;
     int finished;
@@ -145,12 +135,12 @@ static int playCallback( void *inputBuffer, void *outputBuffer,
         for( i=0; i<framesLeft; i++ )
         {
             *wptr++ = *rptr++;  /* left */
-            if( NUM_CHANNELS == 2 ) *wptr++ = *rptr++;  /* right */
+            *wptr++ = *rptr++;  /* right */
         }
         for( ; i<framesPerBuffer; i++ )
         {
             *wptr++ = 0;  /* left */
-            if( NUM_CHANNELS == 2 ) *wptr++ = 0;  /* right */
+            *wptr++ = 0;  /* right */
         }
         data->frameIndex += framesLeft;
         finished = 1;
@@ -160,7 +150,7 @@ static int playCallback( void *inputBuffer, void *outputBuffer,
         for( i=0; i<framesPerBuffer; i++ )
         {
             *wptr++ = *rptr++;  /* left */
-            if( NUM_CHANNELS == 2 ) *wptr++ = *rptr++;  /* right */
+            *wptr++ = *rptr++;  /* right */
         }
         data->frameIndex += framesPerBuffer;
         finished = 0;
@@ -184,7 +174,8 @@ int main(void)
 
     data.maxFrameIndex = totalFrames = NUM_SECONDS * SAMPLE_RATE; /* Record for a few seconds. */
     data.frameIndex = 0;
-    numSamples = totalFrames * NUM_CHANNELS;
+    data.samplesPerFrame = 2;
+    numSamples = totalFrames * data.samplesPerFrame;
 
     numBytes = numSamples * sizeof(SAMPLE);
     data.recordedSamples = (SAMPLE *) malloc( numBytes );
@@ -202,7 +193,7 @@ int main(void)
     err = Pa_OpenStream(
               &stream,
               Pa_GetDefaultInputDeviceID(),
-              NUM_CHANNELS,               /* stereo input */
+              data.samplesPerFrame,               /* stereo input */
               PA_SAMPLE_TYPE,
               NULL,
               paNoDevice,
@@ -212,7 +203,7 @@ int main(void)
               SAMPLE_RATE,
               1024,            /* frames per buffer */
               0,               /* number of buffers, if zero then use default minimum */
-              0, //paDitherOff,    /* flags */
+              paClipOff,  /* we won't output out of range samples so don't bother clipping them */
               recordCallback,
               &data );
     if( err != paNoError ) goto error;
@@ -243,20 +234,10 @@ int main(void)
         }
         average += val;
     }
-    
+    printf("sample max amplitude = %d\n", max );
     average = average / numSamples;
+    printf("sample average = %d\n", average );
 
-    if( PA_SAMPLE_TYPE == paFloat32 )
-    {
-        printf("sample max amplitude = %f\n", max );
-        printf("sample average = %f\n", average );
-    }
-    else
-    {
-        printf("sample max amplitude = %d\n", max );
-        printf("sample average = %d\n", average );
-    }
-    
     /* Write recorded data to a file. */
 #if 0
     {
@@ -268,7 +249,7 @@ int main(void)
         }
         else
         {
-            fwrite( data.recordedSamples, NUM_CHANNELS * sizeof(SAMPLE), totalFrames, fid );
+            fwrite( data.recordedSamples, data.samplesPerFrame * sizeof(SAMPLE), totalFrames, fid );
             fclose( fid );
             printf("Wrote data to 'recorded.raw'\n");
         }
@@ -285,7 +266,7 @@ int main(void)
               PA_SAMPLE_TYPE,
               NULL,
               Pa_GetDefaultOutputDeviceID(),
-              NUM_CHANNELS,               /* stereo output */
+              data.samplesPerFrame,               /* stereo output */
               PA_SAMPLE_TYPE,
               NULL,
               SAMPLE_RATE,
index 1f0dcd7791ea622407b14c86b1151136b3f87330..f6d8f6a4fbb4286f7145661e6b4e0c8cc3203b0f 100644 (file)
@@ -1,4 +1,5 @@
 /*
+ * $Id$
  * $Id$
  * patest_sine.c
  * Play a sine wave using the Portable Audio api for several seconds.
index ea9260389b2e6e79d70dc360fdad458c677b84d3..09abb7b35d61869e8966ac87249a743193ad12e7 100644 (file)
@@ -40,7 +40,7 @@
 
 #define NUM_SECONDS        (20)
 #define SAMPLE_RATE        (44100)
-#define FRAMES_PER_BUFFER  (512)
+#define FRAMES_PER_BUFFER  (256)
 #define LEFT_FREQ          (SAMPLE_RATE/256.0)  /* So we hit 1.0 */
 #define RIGHT_FREQ         (500.0)
 #define AMPLITUDE          (1.0)
@@ -57,22 +57,25 @@ typedef unsigned char       SAMPLE_t;
 #define SAMPLE_ZERO         (0x80)
 #define DOUBLE_TO_SAMPLE(x) (SAMPLE_ZERO + (SAMPLE_t)(127.0 * (x)))
 #define FORMAT_NAME         "Unsigned 8 Bit"
+#endif
 
-#elif TEST_INT8
+#if TEST_INT8
 #define TEST_FORMAT         paInt8
 typedef char                SAMPLE_t;
 #define SAMPLE_ZERO         (0)
 #define DOUBLE_TO_SAMPLE(x) (SAMPLE_ZERO + (SAMPLE_t)(127.0 * (x)))
 #define FORMAT_NAME         "Signed 8 Bit"
+#endif
 
-#elif TEST_INT16
+#if TEST_INT16
 #define TEST_FORMAT         paInt16
 typedef short               SAMPLE_t;
 #define SAMPLE_ZERO         (0)
-#define DOUBLE_TO_SAMPLE(x) (SAMPLE_ZERO + (SAMPLE_t)(32767 * (x)))
+#define DOUBLE_TO_SAMPLE(x) (SAMPLE_ZERO + (SAMPLE_t)(32767.0 * (x)))
 #define FORMAT_NAME         "Signed 16 Bit"
+#endif
 
-#elif TEST_FLOAT32
+#if TEST_FLOAT32
 #define TEST_FORMAT         paFloat32
 typedef float               SAMPLE_t;
 #define SAMPLE_ZERO         (0.0)
index 9c3f0aff93a310be4f41e636b6d1df73340e2d7b..9b9cf3b52db84a4a091663eb76c4858f4de1babb 100644 (file)
 #define NUM_SECONDS   (8)
 #define SAMPLE_RATE   (44100)
 #define FRAMES_PER_BUFFER  (64)
-#define NUM_BUFFERS   (0)
 #ifndef M_PI
 #define M_PI  (3.14159265)
 #endif
 #define TABLE_SIZE   (200)
 typedef struct
 {
-    float         sine[TABLE_SIZE];
-    int           left_phase;
-    int           right_phase;
-    int           framesToGo;
-    volatile PaTimestamp   outTime;
+    float sine[TABLE_SIZE];
+    int left_phase;
+    int right_phase;
+    int framesToGo;
 }
 paTestData;
 /* This routine will be called by the PortAudio engine when audio is needed.
@@ -73,8 +71,6 @@ static int patestCallback(   void *inputBuffer, void *outputBuffer,
     (void) outTime; /* Prevent unused variable warnings. */
     (void) inputBuffer;
 
-    data->outTime = outTime;
-    
     if( data->framesToGo < framesPerBuffer )
     {
         framesToCalc = data->framesToGo;
@@ -104,44 +100,23 @@ static int patestCallback(   void *inputBuffer, void *outputBuffer,
     }
     return finished;
 }
-/*******************************************************************/
-static void ReportStreamTime( PortAudioStream *stream, paTestData *data );
-static void ReportStreamTime( PortAudioStream *stream, paTestData *data )
-{
-    PaTimestamp  streamTime, latency, outTime;
-    
-    streamTime = Pa_StreamTime( stream );
-    outTime = data->outTime;
-    if( outTime < 0.0 )
-    {
-        printf("Stream time = %8.1f\n", streamTime );
-    }
-    else
-    {
-        latency = outTime - streamTime;
-        printf("Stream time = %8.1f, outTime = %8.1f, latency = %8.1f\n",
-            streamTime, outTime, latency );
-    }
-    fflush(stdout);
-}
-
 /*******************************************************************/
 int main(void);
 int main(void)
 {
     PortAudioStream *stream;
     PaError err;
-    paTestData DATA;
+    paTestData data;
     int i;
     int totalSamps;
     printf("PortAudio Test: output sine wave. SR = %d, BufSize = %d\n", SAMPLE_RATE, FRAMES_PER_BUFFER);
     /* initialise sinusoidal wavetable */
     for( i=0; i<TABLE_SIZE; i++ )
     {
-        DATA.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
+        data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
     }
-    DATA.left_phase = DATA.right_phase = 0;
-    DATA.framesToGo = totalSamps =  NUM_SECONDS * SAMPLE_RATE; /* Play for a few seconds. */
+    data.left_phase = data.right_phase = 0;
+    data.framesToGo = totalSamps =  NUM_SECONDS * SAMPLE_RATE; /* Play for a few seconds. */
     err = Pa_Initialize();
     if( err != paNoError ) goto error;
     err = Pa_OpenStream(
@@ -156,41 +131,26 @@ int main(void)
               NULL,
               SAMPLE_RATE,
               FRAMES_PER_BUFFER,            /* frames per buffer */
-              NUM_BUFFERS,              /* number of buffers, if zero then use default minimum */
+              0,              /* number of buffers, if zero then use default minimum */
               paClipOff,      /* we won't output out of range samples so don't bother clipping them */
               patestCallback,
-              &DATA );
+              &data );
     if( err != paNoError ) goto error;
-    
-    DATA.outTime = -1.0; // mark time for callback as undefined
     err = Pa_StartStream( stream );
     if( err != paNoError ) goto error;
-    
     /* Watch until sound is halfway finished. */
     printf("Play for %d seconds.\n", NUM_SECONDS/2 ); fflush(stdout);
-    do
-    {
-        ReportStreamTime( stream, &DATA );
-        Pa_Sleep(100);
-    } while( Pa_StreamTime( stream ) < (totalSamps/2) );
-    
+    while( Pa_StreamTime( stream ) < (totalSamps/2) ) Pa_Sleep(10);
     /* Stop sound until ENTER hit. */
     err = Pa_StopStream( stream );
     if( err != paNoError ) goto error;
     printf("Pause for 2 seconds.\n"); fflush(stdout);
     Pa_Sleep( 2000 );
 
-    DATA.outTime = -1.0; // mark time for callback as undefined
     err = Pa_StartStream( stream );
     if( err != paNoError ) goto error;
-    
     printf("Play until sound is finished.\n"); fflush(stdout);
-    do
-    {
-        ReportStreamTime( stream, &DATA );
-        Pa_Sleep(100);
-    } while( Pa_StreamActive( stream ) );
-    
+    while( Pa_StreamActive( stream ) ) Pa_Sleep(10);
     err = Pa_CloseStream( stream );
     if( err != paNoError ) goto error;
     Pa_Terminate();
diff --git a/pa_tests/patest_toomanysines.c b/pa_tests/patest_toomanysines.c
deleted file mode 100644 (file)
index f78df8c..0000000
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * $Id$
- * Play more sine waves than we can handle in real time as a stress test,
- *
- * Authors:
- *    Ross Bencina <rossb@audiomulch.com>
- *    Phil Burk <philburk@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 <math.h>
-#include "portaudio.h"
-
-#define MAX_SINES     (500)
-#define MAX_LOAD      (1.2)
-#define SAMPLE_RATE   (44100)
-#define FRAMES_PER_BUFFER  (512)
-#ifndef M_PI
-#define M_PI  (3.14159265)
-#endif
-#define TWOPI (M_PI * 2.0)
-
-typedef struct paTestData
-{
-    int numSines;
-    double phases[MAX_SINES];
-}
-paTestData;
-
-/* This routine will be called by the PortAudio engine when audio is needed.
-** It may called at interrupt level on some machines so don't do anything
-** that could mess up the system like calling malloc() or free().
-*/
-static int patestCallback(   void *inputBuffer, void *outputBuffer,
-                             unsigned long framesPerBuffer,
-                             PaTimestamp outTime, void *userData )
-{
-    paTestData *data = (paTestData*)userData;
-    float *out = (float*)outputBuffer;
-    unsigned long i;
-    int j;
-    int finished = 0;
-    (void) outTime; /* Prevent unused variable warnings. */
-    (void) inputBuffer;
-
-    for( i=0; i<framesPerBuffer; i++ )
-    {
-        float output = 0.0;
-        double phaseInc = 0.02;
-        double phase;
-        for( j=0; j<data->numSines; j++ )
-        {
-            /* Advance phase of next oscillator. */
-            phase = data->phases[j];
-            phase += phaseInc;
-            if( phase > TWOPI ) phase -= TWOPI;
-
-            phaseInc *= 1.02;
-            if( phaseInc > 0.5 ) phaseInc *= 0.5;
-
-            /* This is not a very efficient way to calc sines. */
-            output += (float) sin( phase );
-            data->phases[j] = phase;
-        }
-
-
-        *out++ = (float) (output / data->numSines);
-    }
-    return finished;
-}
-
-/*******************************************************************/
-int main(void);
-int main(void)
-{
-    PortAudioStream *stream;
-    PaError err;
-    int numStress;
-    paTestData data = {0};
-    double load;
-    printf("PortAudio Test: output sine wave. SR = %d, BufSize = %d. MAX_LOAD = %f\n",
-        SAMPLE_RATE, FRAMES_PER_BUFFER, MAX_LOAD );
-
-    err = Pa_Initialize();
-    if( err != paNoError ) goto error;
-    err = Pa_OpenStream(
-              &stream,
-              paNoDevice,/* default input device */
-              0,              /* no input */
-              paFloat32,  /* 32 bit floating point input */
-              NULL,
-              Pa_GetDefaultOutputDeviceID(), /* default output device */
-              1,          /* mono output */
-              paFloat32,      /* 32 bit floating point output */
-              NULL,
-              SAMPLE_RATE,
-              FRAMES_PER_BUFFER,            /* frames per buffer */
-              0,              /* number of buffers, if zero then use default minimum */
-              paClipOff,      /* we won't output out of range samples so don't bother clipping them */
-              patestCallback,
-              &data );
-    if( err != paNoError ) goto error;
-    err = Pa_StartStream( stream );
-    if( err != paNoError ) goto error;
-
-    /* Determine number of sines required to get to 50% */
-    do
-    {
-        data.numSines++;
-        Pa_Sleep( 100 );
-
-        load = Pa_GetCPULoad( stream );
-        printf("numSines = %d, CPU load = %f\n", data.numSines, load );
-    }
-    while( load < 0.5 );
-    
-    /* Calculate target stress value then ramp up to that level*/
-    numStress = (int) (2.0 * data.numSines * MAX_LOAD );
-    for( ; data.numSines < numStress; data.numSines++ )
-    {
-        Pa_Sleep( 200 );
-        load = Pa_GetCPULoad( stream );
-        printf("STRESSING: numSines = %d, CPU load = %f\n", data.numSines, load );
-    }
-    
-    printf("Suffer for 5 seconds.\n");
-    Pa_Sleep( 5000 );
-    
-    printf("Stop stream.\n");
-    err = Pa_StopStream( stream );
-    if( err != paNoError ) goto error;
-    
-    err = Pa_CloseStream( stream );
-    if( err != paNoError ) goto error;
-    
-    Pa_Terminate();
-    printf("Test finished.\n");
-    return err;
-error:
-    Pa_Terminate();
-    fprintf( stderr, "An error occured while using the portaudio stream\n" );
-    fprintf( stderr, "Error number: %d\n", err );
-    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
-    return err;
-}
index c24d225deb2be84f8a2f4252844e177d8290a93c..59a33a3ccf434a4f53866a3298b115f7e7e87f0d 100644 (file)
@@ -69,6 +69,7 @@ static int wireCallback( void *inputBuffer, void *outputBuffer,
     SAMPLE *out = (SAMPLE*)outputBuffer;
     SAMPLE *in = (SAMPLE*)inputBuffer;
     unsigned int i;
+    int finished = 0;
     (void) outTime;
 
     /* This may get called with NULL inputBuffer during initial setup. */
@@ -97,12 +98,11 @@ int main(void)
 {
     PortAudioStream *stream;
     PaError err;
-    
+    int numDevices = Pa_CountDevices();
     err = Pa_Initialize();
     if( err != paNoError ) goto error;
-    
-    printf("PortAudio Test: input device ID  = %d\n", Pa_GetDefaultInputDeviceID() );
-    printf("PortAudio Test: output device ID = %d\n", Pa_GetDefaultOutputDeviceID() );
+    printf("PortAudio Test: input device  = %d\n", Pa_GetDefaultInputDeviceID() );
+    printf("PortAudio Test: output device = %d\n", Pa_GetDefaultOutputDeviceID() );
     err = Pa_OpenStream(
               &stream,
               Pa_GetDefaultInputDeviceID(), /* default output device */
@@ -120,19 +120,14 @@ int main(void)
               wireCallback,
               NULL );          /* no data */
     if( err != paNoError ) goto error;
-    
     err = Pa_StartStream( stream );
     if( err != paNoError ) goto error;
-    
     printf("Full duplex sound test in progress.\n");
-    printf("Hit ENTER to exit test.\n");  fflush(stdout);
+    printf("Hit ENTER to exit test.\n");
     getchar();
-    
-    printf("Closing stream.\n");
     err = Pa_CloseStream( stream );
     if( err != paNoError ) goto error;
     Pa_Terminate();
-    
     printf("Full duplex sound test complete.\n"); fflush(stdout);
     return 0;
 error:
index f5015631c40a8c5867f5f7fe38e15d09be2b506f..9f118e12920ffd8f72d48cb697807541c47845df 100644 (file)
@@ -3,18 +3,15 @@
 LIBS =  -lm -lpthread
 
 CDEFINES = -I../pa_common
-CFLAGS = -g -Wall
+CFLAGS = -g
 PASRC = ../pa_common/pa_lib.c pa_unix_oss.c
 PAINC = ../pa_common/portaudio.h
 
 # Tests that work.
 TESTC   = $(PASRC) ../pa_tests/patest_sine.c
-#TESTC   = $(PASRC) ../pa_tests/patest_longsine.c
 #TESTC   = $(PASRC) ../pa_tests/patest_sine_time.c
 #TESTC   = $(PASRC) ../pa_tests/patest_maxsines.c
-#TESTC   = $(PASRC) ../pa_tests/patest_toomanysines.c
-#TESTC   = $(PASRC) ../pa_tests/patest_underflow.c
-#TESTC   = $(PASRC) ../pa_tests/patest_hang.c
+#TESTC   = $(PASRC) ../pa_tests/patest_stop.c
 #TESTC   = $(PASRC) ../pa_tests/patest_sync.c
 #TESTC   = $(PASRC) ../pa_tests/patest_pink.c
 #TESTC   = $(PASRC) ../pa_tests/patest_leftright.c
@@ -28,8 +25,6 @@ TESTC   = $(PASRC) ../pa_tests/patest_sine.c
 #TESTC   = $(PASRC) ../pa_tests/paqa_devs.c
 
 # Tests that do not yet work.
-# OSS doesn't let us make obscenely huge buffers so the test will seem to fail. But its OK.
-#TESTC   = $(PASRC) ../pa_tests/patest_stop.c
 
 TESTH   = $(PAINC)
 
index 97f513d6a79630892eb81efe90a6b76d117ab2de..400de91a27f31b9f6b5b94f1c0b03d228cdb72d9 100644 (file)
@@ -58,16 +58,9 @@ Modfication History
   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.
   
 TODO
+O- change Pa_StreamTime() to query device (patest_sync.c)
 O- put semaphore lock around shared data?
 O- handle native formats better
 O- handle stereo-only device better ???
@@ -98,14 +91,17 @@ PaDriverInfo;
 #include <malloc.h>
 #include <memory.h>
 #include <math.h>
+#include "portaudio.h"
+#include "pa_host.h"
+#include "pa_trace.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 <stdio.h>
+#include <stdlib.h>
 
 #ifdef __linux__
 #include <linux/soundcard.h>
@@ -113,9 +109,13 @@ PaDriverInfo;
 #include <machine/soundcard.h> /* JH20010905 */
 #endif
 
-#include "portaudio.h"
-#include "pa_host.h"
-#include "pa_trace.h"
+#include <sched.h>
+#include <pthread.h>
+
+/* Some versions of OSS do not define AFMT_S16_NE. Assume little endian. FIXME - check CPU*/
+#ifndef AFMT_S16_NE
+ #define AFMT_S16_NE AFMT_S16_LE
+#endif
 
 #define PRINT(x)   { printf x; fflush(stdout); }
 #define ERR_RPT(x) PRINT(x)
@@ -135,9 +135,6 @@ PaDriverInfo;
  #define DEVICE_NAME_BASE            "/dev/audio"
 #endif
 
-/* What is a pthread_t anyway? Here is a guess at a value that will never happen in real life. */ 
-#define INVALID_THREAD              (-1)
-
 #define MAX_CHARS_DEVNAME           (32)
 #define MAX_SAMPLE_RATES            (10)
 typedef struct internalPortAudioDevice
@@ -154,14 +151,7 @@ typedef struct PaHostSoundControl
 {
     int              pahsc_OutputHandle;
     int              pahsc_InputHandle;
-    int              pahsc_AudioPriority;          /* priority of background audio thread */
-    pthread_t        pahsc_AudioThread;            /* background audio thread */
-    pid_t            pahsc_AudioThreadPID;         /* background audio thread */
-    pthread_t        pahsc_WatchDogThread;         /* highest priority thread that protects system */
-    int              pahsc_WatchDogRun;           /* Ask WatchDog to stop. */
-    pthread_t        pahsc_CanaryThread;           /* low priority thread that detects abuse by audio */
-    struct timeval   pahsc_CanaryTime;
-    int              pahsc_CanaryRun;             /* Ask Canary to stop. */
+    pthread_t        pahsc_ThreadPID;
     short           *pahsc_NativeInputBuffer;
     short           *pahsc_NativeOutputBuffer;
     unsigned int     pahsc_BytesPerInputBuffer;    /* native buffer size in bytes */
@@ -169,30 +159,29 @@ typedef struct PaHostSoundControl
     /* 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;
 
 /************************************************* Shared Data ********/
 /* FIXME - put Mutex around this shared data. */
+static int sDeviceIndex = 0;
 static internalPortAudioDevice *sDeviceList = NULL;
 static int sDefaultInputDeviceID = paNoDevice;
 static int sDefaultOutputDeviceID = paNoDevice;
+static int sEnumerationError;
 static int sPaHostError = 0;
 
 /************************************************* Prototypes **********/
 
 static internalPortAudioDevice *Pa_GetInternalDevice( PaDeviceID id );
-static PaError Pa_QueryDevices( void );
+static Pa_QueryDevices( void );
 static PaError Pa_QueryDevice( const char *deviceName, internalPortAudioDevice *pad );
 static PaError Pa_SetupDeviceFormat( int devHandle, int numChannels, int sampleRate );
 
 /********************************* BEGIN CPU UTILIZATION MEASUREMENT ****/
 static void Pa_StartUsageCalculation( internalPortAudioStream   *past )
 {
+    struct itimerval itimer;
     PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;
     if( pahsc == NULL ) return;
     /* Query system timer for usage analysis and to prevent overuse of CPU. */
@@ -235,21 +224,6 @@ static void Pa_EndUsageCalculation( internalPortAudioStream   *past )
 }
 /****************************************** END CPU UTILIZATION *******/
 
-#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.
- */
-static int Get_AFMT_S16_NE( void )
-{
-    long 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
-
 /*********************************************************************
  * Try to open the named device.
  * If it opens, try to set various rates and formats and fill in 
@@ -258,6 +232,7 @@ static int Get_AFMT_S16_NE( void )
 static PaError Pa_QueryDevice( const char *deviceName, internalPortAudioDevice *pad )
 {
     int result = paHostError;
+    int numBytes;
     int tempDevHandle;
     int numChannels, maxNumChannels;
     int format;
@@ -274,7 +249,7 @@ static PaError Pa_QueryDevice( const char *deviceName, internalPortAudioDevice *
      the correct order for OSS is: format, channels, sample rate
      
     */
-    if ( (tempDevHandle = open(deviceName,O_WRONLY|O_NONBLOCK))  == -1 )
+    if ( (tempDevHandle = open(deviceName,O_WRONLY))  == -1 )
     {
         DBUG(("Pa_QueryDevice: could not open %s\n", deviceName ));
         return paHostError;
@@ -400,6 +375,7 @@ error:
 static PaError Pa_QueryDevices( void )
 {
     internalPortAudioDevice *pad, *lastPad;
+    int      numBytes;
     int      go = 1;
     int      numDevices = 0;
     PaError  testResult;
@@ -529,273 +505,55 @@ 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 )
+/*******************************************************************************************/
+static PaError Pa_AudioThreadProc( internalPortAudioStream   *past )
 {
-    int   result = 0;
+    PaError    result = 0;
+    PaHostSoundControl             *pahsc;
+    short    bytes_read = 0;
 
 #ifdef GNUSTEP
     GSRegisterCurrentThread(); /* SB20010904 */
 #endif
 
-    while( pahsc->pahsc_CanaryRun && ((result = usleep( WATCHDOG_INTERVAL_USEC )) == 0) )
-    { 
-        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 )
-{
-    PaError               result = 0;
-    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 && ((result = usleep( WATCHDOG_INTERVAL_USEC )) == 0) )
+#if 1
     {
-        int              delta;
-        struct timeval   currentTime;
-        
-        gettimeofday( &currentTime, NULL );
-
-        /* If audio thread is not advancing, then lower its priority. */
-        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 kill audio and canary. */
-        delta = currentTime.tv_sec - pahsc->pahsc_CanaryTime.tv_sec;
-        if( delta > WATCHDOG_MAX_SECONDS )
-        {
-            ERR_RPT(("PaHost_WatchDogProc: canary died!\n"));
-            goto lowerAudio;
-        }
-    }
+#define SCHEDULER_POLICY SCHED_RR
 
-    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)
+        struct sched_param schp;
+        memset(&schp, 0, sizeof(schp));
+        schp.sched_priority = sched_get_priority_max(SCHEDULER_POLICY);
+
+        if (sched_setscheduler(0, SCHEDULER_POLICY, &schp) != 0)
         {
-            ERR_RPT(("PaHost_WatchDogProc: failed to lower audio priority. errno = %d\n", errno ));
-            /* Fall through into killing audio thread. */
+            perror("sched_setscheduler");
+            printf("PortAudio: only superuser can use real-time priority.\n");
         }
         else
         {
-            ERR_RPT(("PaHost_WatchDogProc: lowered audio priority to prevent hogging of CPU.\n"));
-            goto cleanup;
+            printf("PortAudio: callback priority set to level %d!\n", schp.sched_priority);
         }
     }
-    
-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_CanaryThread = INVALID_THREAD;
-    
-#ifdef GNUSTEP
-    GSUnregisterCurrentThread();  /* SB20010904 */
 #endif
-    return 0;
-}
-
-/*******************************************************************************************/
-static void PaHost_StopWatchDog( PaHostSoundControl   *pahsc )
-{    
-/* Cancel WatchDog thread if there is one. */
-    if( pahsc->pahsc_WatchDogThread != INVALID_THREAD )
-    {
-        pahsc->pahsc_WatchDogRun = 0;
-        DBUG(("PaHost_StopWatchDog: cancel WatchDog\n"));
-        pthread_cancel( pahsc->pahsc_WatchDogThread );
-        pthread_join( pahsc->pahsc_WatchDogThread, NULL );
-        pahsc->pahsc_WatchDogThread = INVALID_THREAD;
-    }
-/* Cancel Canary thread if there is one. */
-    if( pahsc->pahsc_CanaryThread != INVALID_THREAD )
-    {
-        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_CanaryThread = INVALID_THREAD;
-    }
-}
-
-/*******************************************************************************************/
-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*/,
-                      (void*)PaHost_CanaryProc, pahsc);
-    if( hres != 0 )
-    {
-        pahsc->pahsc_CanaryThread = INVALID_THREAD;
-        result = paHostError;
-        sPaHostError = hres;
-        goto error;
-    }
-
-    /* Launch a watchdog thread to prevent runaway audio thread. */
-    pahsc->pahsc_WatchDogRun = 1;
-    hres = pthread_create(&(pahsc->pahsc_WatchDogThread),
-                      NULL /*pthread_attr_t * attr*/,
-                      (void*)PaHost_WatchDogProc, pahsc);
-    if( hres != 0 )
-    {
-        pahsc->pahsc_WatchDogThread = INVALID_THREAD;
-        result = paHostError;
-        sPaHostError = hres;
-        goto error;
-    }
-    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)
-    {
-        PRINT(("PortAudio: only superuser can use real-time priority.\n"));
-    }
-    else
-    {
-        PRINT(("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;
-    count_info   info;
-    int          delta;
 
     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) )
     {
+
+        DBUG(("go!\n"));
         /* Read data from device */
         if(pahsc->pahsc_NativeInputBuffer)
         {
-            DBUG(("Pa_AudioThreadProc: attempt to read %d bytes\n", pahsc->pahsc_BytesPerInputBuffer));
             bytes_read = read(pahsc->pahsc_InputHandle,
                               (void *)pahsc->pahsc_NativeInputBuffer,
                               pahsc->pahsc_BytesPerInputBuffer);
-            DBUG(("Pa_AudioThreadProc: bytes_read = %d\n", bytes_read));
-            if( bytes_read < pahsc->pahsc_BytesPerInputBuffer )
-            {
-                ERR_RPT(("PortAudio: read interrupted! Only got %d bytes.\n", bytes_read ));
-                break;
-            }
+
+            DBUG(("bytes_read: %d\n", bytes_read));
         }
 
         /* Convert 16 bit native data to user data and call user routine. */
@@ -816,37 +574,19 @@ static PaError Pa_AudioThreadProc( internalPortAudioStream   *past )
         if( pahsc->pahsc_NativeOutputBuffer )
         {
 
-            bytes_written = write(pahsc->pahsc_OutputHandle,
+            write(pahsc->pahsc_OutputHandle,
                   (void *)pahsc->pahsc_NativeOutputBuffer,
                   pahsc->pahsc_BytesPerOutputBuffer);
-            if( bytes_written < pahsc->pahsc_BytesPerOutputBuffer )
-            {
-                ERR_RPT(("PortAudio: write interrupted! Only got %d bytes.\n", bytes_written ));
-                break;
-            }
         }
-
-        /* 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;
     }
-    DBUG(("Pa_AudioThreadProc: left audio loop.\n"));
-    
+
     past->past_IsActive = 0;
-    PaHost_StopWatchDog( pahsc );
-    
-error:
-    DBUG(("leaving audio thread.\n"));
+    DBUG(("leaving thread.\n"));
+
 #ifdef GNUSTEP
     GSUnregisterCurrentThread();  /* SB20010904 */
 #endif
-    return result;
+    return 0;
 }
 
 /*******************************************************************************************/
@@ -863,7 +603,7 @@ static PaError Pa_SetupDeviceFormat( int devHandle, int numChannels, int sampleR
         ERR_RPT(("Pa_SetupDeviceFormat: could not SNDCTL_DSP_SETFMT\n" ));
         return paHostError;
     }
-    if( tmp != AFMT_S16_NE )
+    if( tmp != AFMT_S16_NE)
     {
         ERR_RPT(("Pa_SetupDeviceFormat: HW does not support AFMT_S16_NE\n" ));
         return paHostError;
@@ -912,7 +652,7 @@ static int CalcHigherLogTwo( int n )
 static void Pa_SetLatency( int devHandle, int numBuffers, int framesPerBuffer, int channelsPerFrame  )
 {
     int     tmp;
-    int     bufferSize, powerOfTwo;
+    int     numFrames , bufferSize, powerOfTwo;
 
     /* Increase size of buffers and reduce number of buffers to reduce latency inside driver. */
     while( numBuffers > 8 )
@@ -922,7 +662,7 @@ static void Pa_SetLatency( int devHandle, int numBuffers, int framesPerBuffer, i
     }
 
     /* calculate size of buffers in bytes */
-    bufferSize = framesPerBuffer * channelsPerFrame * sizeof(short); /* FIXME - other sizes? */
+    bufferSize = framesPerBuffer * channelsPerFrame * sizeof(short); /* FIXME */
 
     /* Calculate next largest power of two */
     powerOfTwo = CalcHigherLogTwo( bufferSize );
@@ -975,6 +715,9 @@ PaError PaHost_OpenStream( internalPortAudioStream   *past )
 {
     PaError          result = paNoError;
     PaHostSoundControl *pahsc;
+    int tmp;
+    int flags;
+    int              numBytes, maxChannels;
     unsigned int     minNumBuffers;
     internalPortAudioDevice *pad;
     DBUG(("PaHost_OpenStream() called.\n" ));
@@ -991,8 +734,6 @@ PaError PaHost_OpenStream( internalPortAudioStream   *past )
 
     pahsc->pahsc_OutputHandle = BAD_DEVICE_ID; /* No device currently opened. */
     pahsc->pahsc_InputHandle = BAD_DEVICE_ID;
-    pahsc->pahsc_AudioThread = INVALID_THREAD;
-    pahsc->pahsc_WatchDogThread = INVALID_THREAD;
 
     /* Allocate native buffers. */
     pahsc->pahsc_BytesPerInputBuffer = past->past_FramesPerUserBuffer *
@@ -1035,18 +776,6 @@ PaError PaHost_OpenStream( internalPortAudioStream   *past )
         {
             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)
@@ -1068,17 +797,6 @@ PaError PaHost_OpenStream( internalPortAudioStream   *past )
         {
             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)
             {
@@ -1097,17 +815,6 @@ PaError PaHost_OpenStream( internalPortAudioStream   *past )
         {
             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)
             {
@@ -1162,14 +869,13 @@ PaError PaHost_StartEngine( internalPortAudioStream *past )
      *   - 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),
+    hres = pthread_create(&(pahsc->pahsc_ThreadPID),
                           NULL /*pthread_attr_t * attr*/,
                           (void*)Pa_AudioThreadProc, past);
     if( hres != 0 )
     {
         result = paHostError;
         sPaHostError = hres;
-        pahsc->pahsc_AudioThread = INVALID_THREAD;
         goto error;
     }
 
@@ -1181,6 +887,7 @@ error:
 PaError PaHost_StopEngine( internalPortAudioStream *past, int abort )
 {
     int                 hres;
+    long                timeOut;
     PaError             result = paNoError;
     PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;
 
@@ -1192,12 +899,12 @@ PaError PaHost_StopEngine( internalPortAudioStream *past, int abort )
     if( abort ) past->past_StopNow = 1;
 
     /* Join thread to recover memory resources. */
-    if( pahsc->pahsc_AudioThread != INVALID_THREAD )
+    if( pahsc->pahsc_ThreadPID != -1 )
     {
         /* This check is needed for GNUSTEP - SB20010904 */
-        if ( !pthread_equal( pahsc->pahsc_AudioThread, pthread_self() ) )
+        if ( !pthread_equal( pahsc->pahsc_ThreadPID, pthread_self() ) )
         {
-            hres = pthread_join( pahsc->pahsc_AudioThread, NULL );
+            hres = pthread_join( pahsc->pahsc_ThreadPID, NULL );
         }
         else
         {
@@ -1210,7 +917,7 @@ PaError PaHost_StopEngine( internalPortAudioStream *past, int abort )
             result = paHostError;
             sPaHostError = hres;
         }
-        pahsc->pahsc_AudioThread = INVALID_THREAD;
+        pahsc->pahsc_ThreadPID = -1;
     }
 
     past->past_IsActive = 0;
@@ -1322,7 +1029,7 @@ void Pa_Sleep( long msec )
  */
 void *PaHost_AllocateFastMemory( long numBytes )
 {
-    void *addr = malloc( numBytes ); /* FIXME - do we need physical, wired, non-virtual memory? */
+    void *addr = malloc( numBytes ); /* FIXME - do we need physical memory? */
     if( addr != NULL ) memset( addr, 0, numBytes );
     return addr;
 }
@@ -1351,23 +1058,11 @@ PaError PaHost_StreamActive( internalPortAudioStream   *past )
 PaTimestamp Pa_StreamTime( PortAudioStream *stream )
 {
     internalPortAudioStream *past = (internalPortAudioStream *) stream;
-    PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;
-    count_info    info;
-    int           delta;
-
+    /* FIXME - return actual frames played, not frames generated.
+    ** Need to query the output device somehow.
+    */
     if( past == NULL ) return paBadStreamPtr;
-
-    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));
-
-    }
+    return past->past_FrameCount;
 }
 
 /***********************************************************************/
index 877c01d4767d001448d733f51aba55337e259518..96f47532642902d4c0b13ed1bce7326bf16c809e 100644 (file)
@@ -33,7 +33,6 @@
 /* Modifications
  *    7/19/01 Mike Berry - casts for compiling with __MWERKS__ CodeWarrior
  *    9/27/01 Phil Burk - use number of frames instead of real-time for CPULoad calculation.
- *    4/19/02 Phil Burk - Check for Win XP for system latency calculation.
  */
 /* Compiler flags:
  SUPPORT_AUDIO_CAPTURE - define this flag if you want to SUPPORT_AUDIO_CAPTURE
 #include "pa_host.h"
 #include "pa_trace.h"
 #include "dsound_wrapper.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 PA_USE_HIGH_LATENCY   (0)
 #if PA_USE_HIGH_LATENCY
 #define PA_WIN_9X_LATENCY     (500)
@@ -64,9 +61,6 @@
 #define PA_WIN_9X_LATENCY     (140)
 #define PA_WIN_NT_LATENCY     (280)
 #endif
-
-#define PA_WIN_WDM_LATENCY       (120)
-
 /* Trigger an underflow for testing purposes. Should normally be (0). */
 #define PA_SIMULATE_UNDERFLOW (0)
 #if PA_SIMULATE_UNDERFLOW
@@ -74,7 +68,6 @@ static  gUnderCallbackCounter = 0;
 #define UNDER_START_GAP       (10)
 #define UNDER_STOP_GAP        (UNDER_START_GAP + 4)
 #endif
-
 /************************************************* Definitions ********/
 typedef struct internalPortAudioStream internalPortAudioStream;
 typedef struct internalPortAudioDevice
@@ -85,7 +78,6 @@ typedef struct internalPortAudioDevice
     PaDeviceInfo                     pad_Info;
 }
 internalPortAudioDevice;
-
 /* Define structure to contain all DirectSound and Windows specific data. */
 typedef struct PaHostSoundControl
 {
@@ -101,7 +93,6 @@ typedef struct PaHostSoundControl
     double           pahsc_InverseTicksPerUserBuffer;
 }
 PaHostSoundControl;
-
 /************************************************* Shared Data ********/
 /* FIXME - put Mutex around this shared data. */
 static int sNumDevices = 0;
@@ -124,7 +115,6 @@ static BOOL CALLBACK Pa_CountDevProc(LPGUID lpGUID,
 static Pa_QueryDevices( void );
 static void CALLBACK Pa_TimerCallback(UINT uID, UINT uMsg,
                                       DWORD dwUser, DWORD dw1, DWORD dw2);
-
 /********************************* BEGIN CPU UTILIZATION MEASUREMENT ****/
 static void Pa_StartUsageCalculation( internalPortAudioStream   *past )
 {
@@ -133,7 +123,6 @@ static void Pa_StartUsageCalculation( internalPortAudioStream   *past )
     /* Query system timer for usage analysis and to prevent overuse of CPU. */
     QueryPerformanceCounter( &pahsc->pahsc_EntryCount );
 }
-
 static void Pa_EndUsageCalculation( internalPortAudioStream   *past )
 {
     LARGE_INTEGER CurrentCount = { 0, 0 };
@@ -153,7 +142,6 @@ static void Pa_EndUsageCalculation( internalPortAudioStream   *past )
                            (LOWPASS_COEFFICIENT_1 * newUsage);
     }
 }
-
 /****************************************** END CPU UTILIZATION *******/
 static PaError Pa_QueryDevices( void )
 {
@@ -885,38 +873,6 @@ PaError PaHost_CloseStream( internalPortAudioStream   *past )
     past->past_DeviceData = NULL;
     return paNoError;
 }
-
-/* Set minimal latency based on whether NT or Win95.
- * NT has higher latency.
- */
-static int PaHost_GetMinSystemLatency( void )
-{
-    int minLatencyMsec;
-    /* Set minimal latency based on whether NT or other OS.
-     * NT has higher latency.
-     */
-    OSVERSIONINFO osvi;
-       osvi.dwOSVersionInfoSize = sizeof( osvi );
-       GetVersionEx( &osvi );
-    DBUG(("PA - PlatformId = 0x%x\n", osvi.dwPlatformId ));
-    DBUG(("PA - MajorVersion = 0x%x\n", osvi.dwMajorVersion ));
-    DBUG(("PA - MinorVersion = 0x%x\n", osvi.dwMinorVersion ));
-    /* Check for NT */
-       if( (osvi.dwMajorVersion == 4) && (osvi.dwPlatformId == 2) )
-       {
-               minLatencyMsec = PA_WIN_NT_LATENCY;
-       }
-       else if(osvi.dwMajorVersion >= 5)
-       {
-               minLatencyMsec = PA_WIN_WDM_LATENCY;
-       }
-       else
-       {
-               minLatencyMsec = PA_WIN_9X_LATENCY;
-       }
-    return minLatencyMsec;
-}
-
 /*************************************************************************
 ** Determine minimum number of buffers required for this host based
 ** on minimum latency. Latency can be optionally set by user by setting
@@ -932,6 +888,7 @@ static int PaHost_GetMinSystemLatency( void )
 int Pa_GetMinNumBuffers( int framesPerBuffer, double sampleRate )
 {
     char      envbuf[PA_ENV_BUF_SIZE];
+    DWORD     hostVersion;
     DWORD     hresult;
     int       minLatencyMsec = 0;
     double    msecPerBuffer = (1000.0 * framesPerBuffer) / sampleRate;
@@ -944,7 +901,12 @@ int Pa_GetMinNumBuffers( int framesPerBuffer, double sampleRate )
     }
     else
     {
-        minLatencyMsec = PaHost_GetMinSystemLatency();
+        /* Set minimal latency based on whether NT or Win95.
+         * NT has higher latency.
+         */
+        hostVersion = GetVersion();
+        /* High bit clear if NT */
+        minLatencyMsec = ( (hostVersion & 0x80000000) == 0 ) ? PA_WIN_NT_LATENCY : PA_WIN_9X_LATENCY  ;
 #if PA_USE_HIGH_LATENCY
         PRINT(("PA - Minimum Latency set to %d msec!\n", minLatencyMsec ));
 #endif
index ba7ca62c7d3fc9d068ed3f67df5c92fdfbdb8ef6..2b3dea23d249be748b1e97abd1c8510527048a21 100644 (file)
 /* Modification History:
  PLB = Phil Burk
  JM = Julien Maillard
- RDB = Ross Bencina
  PLB20010402 - sDevicePtrs now allocates based on sizeof(pointer)
  PLB20010413 - check for excessive numbers of channels
  PLB20010422 - apply Mike Berry's changes for CodeWarrior on PC
                including condition including of memory.h,
-               and explicit typecasting on memory allocation
+      and explicit typecasting on memory allocation
  PLB20010802 - use GlobalAlloc for sDevicesPtr instead of PaHost_AllocFastMemory
  PLB20010816 - pass process instead of thread to SetPriorityClass()
  PLB20010927 - use number of frames instead of real-time for CPULoad calculation.
  JM20020118 - prevent hung thread when buffers underflow.
- PLB20020321 - detect Win XP versus NT, 9x; fix DBUG typo; removed init of CurrentCount
- RDB20020411 - various renaming cleanups, factored streamData alloc and cpu usage init
- RDB20020417 - stopped counting WAVE_MAPPER when there were no real devices
-               refactoring, renaming and fixed a few edge case bugs
 */
 
 #include <stdio.h>
 #include "pa_trace.h"
 
 /************************************************* Constants ********/
-#define PA_TRACK_MEMORY          (0)
-
 #define PA_USE_TIMER_CALLBACK    (0)  /* Select between two options for background task. 0=thread, 1=timer */
+#define PA_USE_HIGH_LATENCY      (0)  /* For debugging glitches. */
 /* Switches for debugging. */
 #define PA_SIMULATE_UNDERFLOW    (0)  /* Set to one to force an underflow of the output buffer. */
-
 /* To trace program, enable TRACE_REALTIME_EVENTS in pa_trace.h */
 #define PA_TRACE_RUN             (0)
 #define PA_TRACE_START_STOP      (1)
-
-#define PA_USE_HIGH_LATENCY      (0)  /* For debugging glitches. */
-
 #if PA_USE_HIGH_LATENCY
  #define PA_MIN_MSEC_PER_HOST_BUFFER  (100)
  #define PA_MAX_MSEC_PER_HOST_BUFFER  (300) /* Do not exceed unless user buffer exceeds */
  #define PA_WIN_9X_LATENCY            (200)
 #endif
 #define MIN_TIMEOUT_MSEC                 (1000)
-
 /*
 ** Use higher latency for NT because it is even worse at real-time
 ** operation than Win9x.
 */
 #define PA_WIN_NT_LATENCY        (PA_WIN_9X_LATENCY * 2)
-#define PA_WIN_WDM_LATENCY       (PA_WIN_9X_LATENCY)
 
 #if PA_SIMULATE_UNDERFLOW
 static  gUnderCallbackCounter = 0;
@@ -114,52 +102,52 @@ static  gUnderCallbackCounter = 0;
 
 #define PRINT(x) { printf x; fflush(stdout); }
 #define ERR_RPT(x) PRINT(x)
-#define DBUG(x)  /* PRINT(x) /**/
+#define DBUG(x)  /* PRINT(x) */
 #define DBUGX(x) /* PRINT(x) */
 /************************************************* Definitions ********/
 /**************************************************************
  * Structure for internal host specific stream data.
  * This is allocated on a per stream basis.
  */
-typedef struct PaWMMEStreamData
+typedef struct PaHostSoundControl
 {
     /* Input -------------- */
-    HWAVEIN            hWaveIn;
-    WAVEHDR           *inputBuffers;
-    int                currentInputBuffer;
-    int                bytesPerHostInputBuffer;
-    int                bytesPerUserInputBuffer;    /* native buffer size in bytes */
+    HWAVEIN            pahsc_HWaveIn;
+    WAVEHDR           *pahsc_InputBuffers;
+    int                pahsc_CurrentInputBuffer;
+    int                pahsc_BytesPerHostInputBuffer;
+    int                pahsc_BytesPerUserInputBuffer;    /* native buffer size in bytes */
     /* Output -------------- */
-    HWAVEOUT           hWaveOut;
-    WAVEHDR           *outputBuffers;
-    int                currentOutputBuffer;
-    int                bytesPerHostOutputBuffer;
-    int                bytesPerUserOutputBuffer;    /* native buffer size in bytes */
+    HWAVEOUT           pahsc_HWaveOut;
+    WAVEHDR           *pahsc_OutputBuffers;
+    int                pahsc_CurrentOutputBuffer;
+    int                pahsc_BytesPerHostOutputBuffer;
+    int                pahsc_BytesPerUserOutputBuffer;    /* native buffer size in bytes */
     /* Run Time -------------- */
-    PaTimestamp        framesPlayed;
-    long               lastPosition;                /* used to track frames played. */
+    PaTimestamp        pahsc_FramesPlayed;
+    long               pahsc_LastPosition;                /* used to track frames played. */
     /* For measuring CPU utilization. */
-    LARGE_INTEGER      entryCount;
-    double             inverseTicksPerHostBuffer;
+    LARGE_INTEGER      pahsc_EntryCount;
+    double             pahsc_InverseTicksPerHostBuffer;
     /* Init Time -------------- */
-    int                numHostBuffers;
-    int                framesPerHostBuffer;
-    int                userBuffersPerHostBuffer;
-    CRITICAL_SECTION   streamLock;                  /* Mutext to prevent threads from colliding. */
-    INT                streamLockInited;
+    int                pahsc_NumHostBuffers;
+    int                pahsc_FramesPerHostBuffer;
+    int                pahsc_UserBuffersPerHostBuffer;
+    CRITICAL_SECTION   pahsc_StreamLock;                  /* Mutext to prevent threads from colliding. */
+    INT                pahsc_StreamLockInited;
 #if PA_USE_TIMER_CALLBACK
-    BOOL               ifInsideCallback;            /* Test for reentrancy. */
-    MMRESULT           timerID;
+    BOOL               pahsc_IfInsideCallback;            /* Test for reentrancy. */
+    MMRESULT           pahsc_TimerID;
 #else
-    HANDLE             abortEvent;
-    int                abortEventInited;
-    HANDLE             bufferEvent;
-    int                bufferEventInited;
-    HANDLE             engineThread;
-    DWORD              engineThreadID;
+    HANDLE             pahsc_AbortEvent;
+    int                pahsc_AbortEventInited;
+    HANDLE             pahsc_BufferEvent;
+    int                pahsc_BufferEventInited;
+    HANDLE             pahsc_EngineThread;
+    DWORD              pahsc_EngineThreadID;
 #endif
 }
-PaWMMEStreamData;
+PaHostSoundControl;
 /************************************************* Shared Data ********/
 /* FIXME - put Mutex around this shared data. */
 static int sNumInputDevices = 0;
@@ -171,169 +159,64 @@ static int sDefaultOutputDeviceID = paNoDevice;
 static int sPaHostError = 0;
 static const char sMapperSuffixInput[] = " - Input";
 static const char sMapperSuffixOutput[] = " - Output";
-
-#if PA_TRACK_MEMORY
-static int sNumAllocations = 0;
-#endif
-
 /************************************************* Macros ********/
 /* Convert external PA ID to an internal ID that includes WAVE_MAPPER */
 #define PaDeviceIdToWinId(id) (((id) < sNumInputDevices) ? (id - 1) : (id - sNumInputDevices - 1))
 /************************************************* Prototypes **********/
-
-void Pa_InitializeNumDevices( void );
-PaError Pa_AllocateDevicePtrs( void );
-
+static Pa_QueryDevices( void );
 static void CALLBACK Pa_TimerCallback(UINT uID, UINT uMsg,
                                       DWORD dwUser, DWORD dw1, DWORD dw2);
 PaError PaHost_GetTotalBufferFrames( internalPortAudioStream   *past );
-static PaError PaHost_UpdateStreamTime( PaWMMEStreamData *wmmeStreamData );
+static PaError PaHost_UpdateStreamTime( PaHostSoundControl *pahsc );
 static PaError PaHost_BackgroundManager( internalPortAudioStream   *past );
 
-static void *PaHost_AllocateTrackedMemory( long numBytes );
-static void PaHost_FreeTrackedMemory( void *addr );
-
-/*******************************************************************/
-static PaError PaHost_AllocateWMMEStreamData( internalPortAudioStream *stream )
-{
-    PaError             result = paNoError;
-    PaWMMEStreamData *wmmeStreamData;
-    
-    wmmeStreamData = (PaWMMEStreamData *) PaHost_AllocateFastMemory(sizeof(PaWMMEStreamData)); /* MEM */
-    if( wmmeStreamData == NULL )
-    {
-        result = paInsufficientMemory;
-        goto error;
-    }
-    memset( wmmeStreamData, 0, sizeof(PaWMMEStreamData) );
-    stream->past_DeviceData = (void *) wmmeStreamData;
-
-    return result;
-    
-error:
-    return result;
-}
-
-/*******************************************************************/
-static void PaHost_FreeWMMEStreamData( internalPortAudioStream *internalStream )
-{
-    PaWMMEStreamData *wmmeStreamData = (PaWMMEStreamData *) internalStream->past_DeviceData;
-
-    PaHost_FreeFastMemory( wmmeStreamData, sizeof(PaWMMEStreamData) ); /* MEM */
-    internalStream->past_DeviceData = NULL;
-}
-/*************************************************************************/
-static PaWMMEStreamData* PaHost_GetWMMEStreamData( internalPortAudioStream* internalStream )
-{
-    PaWMMEStreamData *result = NULL;
-
-    if( internalStream != NULL )
-    {
-        result = (PaWMMEStreamData *) internalStream->past_DeviceData;
-    }
-    return result;
-}
 /********************************* BEGIN CPU UTILIZATION MEASUREMENT ****/
-/* FIXME: the cpu usage code should be factored out into a common module */
-static void Pa_InitializeCpuUsageScalar( internalPortAudioStream   *stream )
+static void Pa_StartUsageCalculation( internalPortAudioStream   *past )
 {
-    PaWMMEStreamData *wmmeStreamData = (PaWMMEStreamData *) stream->past_DeviceData;
-
-    LARGE_INTEGER frequency;
-    if( QueryPerformanceFrequency( &frequency ) == 0 )
-    {
-        wmmeStreamData->inverseTicksPerHostBuffer = 0.0;
-    }
-    else
-    {
-        wmmeStreamData->inverseTicksPerHostBuffer = stream->past_SampleRate /
-                ( (double)frequency.QuadPart * stream->past_FramesPerUserBuffer * wmmeStreamData->userBuffersPerHostBuffer );
-        DBUG(("inverseTicksPerHostBuffer = %g\n", wmmeStreamData->inverseTicksPerHostBuffer ));
-    }
-}
-static void Pa_StartUsageCalculation( internalPortAudioStream   *stream )
-{
-    PaWMMEStreamData *wmmeStreamData = (PaWMMEStreamData *) stream->past_DeviceData;
-
-    if( wmmeStreamData == NULL ) return;
+    PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;
+    if( pahsc == NULL ) return;
     /* Query system timer for usage analysis and to prevent overuse of CPU. */
-    QueryPerformanceCounter( &wmmeStreamData->entryCount );
+    QueryPerformanceCounter( &pahsc->pahsc_EntryCount );
 }
-static void Pa_EndUsageCalculation( internalPortAudioStream   *stream )
+static void Pa_EndUsageCalculation( internalPortAudioStream   *past )
 {
-    LARGE_INTEGER CurrentCount;
-    PaWMMEStreamData *wmmeStreamData = (PaWMMEStreamData *) stream->past_DeviceData;
-
-    if( wmmeStreamData == NULL ) return;
+    LARGE_INTEGER CurrentCount = { 0, 0 };
+    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.
-     */
+    ** Measure CPU utilization during this callback. Note that this calculation
+    ** assumes that we had the processor the whole time.
+    */
 #define LOWPASS_COEFFICIENT_0   (0.9)
 #define LOWPASS_COEFFICIENT_1   (0.99999 - LOWPASS_COEFFICIENT_0)
     if( QueryPerformanceCounter( &CurrentCount ) )
     {
-        LONGLONG InsideCount = CurrentCount.QuadPart - wmmeStreamData->entryCount.QuadPart;
-        double newUsage = InsideCount * wmmeStreamData->inverseTicksPerHostBuffer;
-        stream->past_Usage = (LOWPASS_COEFFICIENT_0 * stream->past_Usage) +
-                             (LOWPASS_COEFFICIENT_1 * newUsage);
+        LONGLONG InsideCount = CurrentCount.QuadPart - pahsc->pahsc_EntryCount.QuadPart;
+        double newUsage = InsideCount * pahsc->pahsc_InverseTicksPerHostBuffer;
+        past->past_Usage = (LOWPASS_COEFFICIENT_0 * past->past_Usage) +
+                           (LOWPASS_COEFFICIENT_1 * newUsage);
     }
 }
 /****************************************** END CPU UTILIZATION *******/
 
-static void Pa_InitializeNumDevices( void )
-{
-    sNumInputDevices = waveInGetNumDevs();
-    if( sNumInputDevices > 0 )
-    {
-        sNumInputDevices += 1; /* add one extra for the WAVE_MAPPER */
-        sDefaultInputDeviceID = 0;
-    }
-    else
-    {
-        sDefaultInputDeviceID = paNoDevice;
-    }
-
-    sNumOutputDevices = waveOutGetNumDevs();
-    if( sNumOutputDevices > 0 )
-    {
-        sNumOutputDevices += 1; /* add one extra for the WAVE_MAPPER */
-        sDefaultOutputDeviceID = sNumInputDevices;
-    }
-    else
-    {
-        sDefaultOutputDeviceID = paNoDevice;
-    }
-
-    sNumDevices = sNumInputDevices + sNumOutputDevices;
-}
-
-static PaError Pa_AllocateDevicePtrs( void )
+static PaError Pa_QueryDevices( void )
 {
     int numBytes;
-    int i;
-
+    /* Count the devices and add one extra for the WAVE_MAPPER */
+    sNumInputDevices = waveInGetNumDevs() + 1;
+    sDefaultInputDeviceID = 0;
+    sNumOutputDevices = waveOutGetNumDevs() + 1;
+    sDefaultOutputDeviceID = sNumInputDevices;
+    sNumDevices = sNumInputDevices + sNumOutputDevices;
     /* Allocate structures to hold device info. */
     /* PLB20010402 - was allocating too much memory. */
     /* numBytes = sNumDevices * sizeof(PaDeviceInfo);  // PLB20010402 */
-
-    if( sNumDevices > 0 )
-    {
-        numBytes = sNumDevices * sizeof(PaDeviceInfo *); /* PLB20010402 */
-        sDevicePtrs = (PaDeviceInfo **) PaHost_AllocateTrackedMemory( numBytes ); /* MEM */
-        if( sDevicePtrs == NULL ) return paInsufficientMemory;
-
-        for( i = 0; i < sNumDevices; i++ )
-            sDevicePtrs[i] = NULL;  /* RDB20020417 explicitly set each ptr to NULL */
-    }
-    else
-    {
-        sDevicePtrs = NULL;
-    }
-    
+    numBytes = sNumDevices * sizeof(PaDeviceInfo *); /* PLB20010402 */
+    sDevicePtrs = (PaDeviceInfo **) GlobalAlloc( GPTR, numBytes ); /* MEM */
+    if( sDevicePtrs == NULL ) return paInsufficientMemory;
     return paNoError;
 }
-/*************************************************************************/
+/************************************************************************************/
 long Pa_GetHostError()
 {
     return sPaHostError;
@@ -341,18 +224,16 @@ long Pa_GetHostError()
 /*************************************************************************/
 int Pa_CountDevices()
 {
-    if( PaHost_IsInitialized() )
-        return sNumDevices;
-    else
-        return 0;
+    if( sNumDevices <= 0 ) Pa_Initialize();
+    return sNumDevices;
 }
 /*************************************************************************
- * If a PaDeviceInfo structure has not already been created,
- * then allocate one and fill it in for the selected device.
- *
- * We create one extra input and one extra output device for the WAVE_MAPPER.
- * [Does anyone know how to query the default device and get its name?]
- */
+** If a PaDeviceInfo structure has not already been created,
+** then allocate one and fill it in for the selected device.
+**
+** We create one extra input and one extra output device for the WAVE_MAPPER.
+** [Does anyone know how to query the default device and get its name?]
+*/
 const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceID id )
 {
 #define NUM_STANDARDSAMPLINGRATES   3   /* 11.025, 22.05, 44.1 */
@@ -370,19 +251,19 @@ const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceID id )
     {
         return sDevicePtrs[ id ];
     }
-    deviceInfo = (PaDeviceInfo *)PaHost_AllocateTrackedMemory( sizeof(PaDeviceInfo) ); /* MEM */
+    deviceInfo = (PaDeviceInfo *)GlobalAlloc( GPTR, sizeof(PaDeviceInfo) ); /* MEM */
     if( deviceInfo == NULL ) return NULL;
     deviceInfo->structVersion = 1;
     deviceInfo->maxInputChannels = 0;
     deviceInfo->maxOutputChannels = 0;
     deviceInfo->numSampleRates = 0;
-    sampleRates = (double*)PaHost_AllocateTrackedMemory( MAX_NUMSAMPLINGRATES * sizeof(double) ); /* MEM */
+    sampleRates = (double*)GlobalAlloc( GPTR, MAX_NUMSAMPLINGRATES * sizeof(double) ); /* MEM */
     deviceInfo->sampleRates = sampleRates;
     deviceInfo->nativeSampleFormats = paInt16;       /* should query for higher bit depths below */
     if( id < sNumInputDevices )
     {
         /* input device */
-        int inputMmID = PaDeviceIdToWinId(id);
+        int inputMmID = id - 1; /* WAVE_MAPPER is -1 so we start with WAVE_MAPPER */
         WAVEINCAPS wic;
         if( waveInGetDevCaps( inputMmID, &wic, sizeof( WAVEINCAPS ) ) != MMSYSERR_NOERROR )
             goto error;
@@ -390,21 +271,21 @@ const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceID id )
         /* Append I/O suffix to WAVE_MAPPER device. */
         if( inputMmID == WAVE_MAPPER )
         {
-            s = (char *) PaHost_AllocateTrackedMemory( strlen( wic.szPname ) + 1 + sizeof(sMapperSuffixInput) ); /* MEM */
+            s = (char *) GlobalAlloc( GMEM_FIXED, strlen( wic.szPname ) + 1 + sizeof(sMapperSuffixInput) ); /* MEM */
             strcpy( s, wic.szPname );
             strcat( s, sMapperSuffixInput );
         }
         else
         {
-            s = (char *) PaHost_AllocateTrackedMemory( strlen( wic.szPname ) + 1 ); /* MEM */
+            s = (char *) GlobalAlloc( GMEM_FIXED, strlen( wic.szPname ) + 1 ); /* MEM */
             strcpy( s, wic.szPname );
         }
         deviceInfo->name = s;
         deviceInfo->maxInputChannels = wic.wChannels;
         /* Sometimes a device can return a rediculously large number of channels.
-         * This happened with an SBLive card on a Windows ME box.
-         * If that happens, then force it to 2 channels.  PLB20010413
-         */
+        ** This happened with an SBLive card on a Windows ME box.
+        ** If that happens, then force it to 2 channels.  PLB20010413
+        */
         if( (deviceInfo->maxInputChannels < 1) || (deviceInfo->maxInputChannels > 256) )
         {
             ERR_RPT(("Pa_GetDeviceInfo: Num input channels reported as %d! Changed to 2.\n", deviceInfo->maxOutputChannels ));
@@ -440,62 +321,33 @@ const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceID id )
     else if( id - sNumInputDevices < sNumOutputDevices )
     {
         /* output device */
-        int outputMmID = PaDeviceIdToWinId(id);
+        int outputMmID = id - sNumInputDevices - 1;
         WAVEOUTCAPS woc;
         if( waveOutGetDevCaps( outputMmID, &woc, sizeof( WAVEOUTCAPS ) ) != MMSYSERR_NOERROR )
             goto error;
         /* Append I/O suffix to WAVE_MAPPER device. */
         if( outputMmID == WAVE_MAPPER )
         {
-            s = (char *) PaHost_AllocateTrackedMemory( strlen( woc.szPname ) + 1 + sizeof(sMapperSuffixOutput) );  /* MEM */
+            s = (char *) GlobalAlloc( GMEM_FIXED, strlen( woc.szPname ) + 1 + sizeof(sMapperSuffixOutput) );  /* MEM */
             strcpy( s, woc.szPname );
             strcat( s, sMapperSuffixOutput );
         }
         else
         {
-            s = (char *) PaHost_AllocateTrackedMemory( strlen( woc.szPname ) + 1 );  /* MEM */
+            s = (char *) GlobalAlloc( GMEM_FIXED, strlen( woc.szPname ) + 1 );  /* MEM */
             strcpy( s, woc.szPname );
         }
         deviceInfo->name = s;
         deviceInfo->maxOutputChannels = woc.wChannels;
         /* Sometimes a device can return a rediculously large number of channels.
-         * This happened with an SBLive card on a Windows ME box.
-         * It also happens on Win XP!
-         */
+        ** This happened with an SBLive card on a Windows ME box.
+        ** If that happens, then force it to 2 channels. PLB20010413
+        */
         if( (deviceInfo->maxOutputChannels < 1) || (deviceInfo->maxOutputChannels > 256) )
         {
-#if 1
+            ERR_RPT(("Pa_GetDeviceInfo: Num output channels reported as %d! Changed to 2.\n", deviceInfo->maxOutputChannels ));
             deviceInfo->maxOutputChannels = 2;
-#else
-        /* If channel max is goofy, then query for max channels. PLB20020228
-         * This doesn't seem to help. Disable code for now. Remove it later.
-         */
-            ERR_RPT(("Pa_GetDeviceInfo: Num output channels reported as %d!", deviceInfo->maxOutputChannels ));
-            deviceInfo->maxOutputChannels = 0;
-                       /* Attempt to find the correct maximum by querying the device. */
-                       for( i=2; i<16; i += 2 )
-                       {
-                               WAVEFORMATEX wfx;
-                               wfx.wFormatTag = WAVE_FORMAT_PCM;
-                               wfx.nSamplesPerSec = 44100;
-                               wfx.wBitsPerSample = 16;
-                               wfx.cbSize = 0; /* ignored */
-                               wfx.nChannels = (WORD) i;
-                               wfx.nAvgBytesPerSec = wfx.nChannels * wfx.nSamplesPerSec * sizeof(short);
-                               wfx.nBlockAlign = (WORD)(wfx.nChannels * sizeof(short));
-                               if( waveOutOpen( NULL, outputMmID, &wfx, 0, 0, WAVE_FORMAT_QUERY ) == MMSYSERR_NOERROR )
-                               {
-                                       deviceInfo->maxOutputChannels = i;
-                               }
-                               else
-                               {
-                                       break;
-                               }
-                       }
-#endif
-            ERR_RPT((" Changed to %d.\n", deviceInfo->maxOutputChannels ));
         }
-
         /* Add a sample rate to the list if we can do stereo 16 bit at that rate
          * based on the format flags. */
         if( woc.dwFormats & WAVE_FORMAT_1M16 ||woc.dwFormats & WAVE_FORMAT_1S16 )
@@ -504,7 +356,6 @@ const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceID id )
             sampleRates[ deviceInfo->numSampleRates++ ] = 22050.;
         if( woc.dwFormats & WAVE_FORMAT_4M16 ||woc.dwFormats & WAVE_FORMAT_4S16 )
             sampleRates[ deviceInfo->numSampleRates++ ] = 44100.;
-
         /* Add a sample rate to the list if we can do stereo 16 bit at that rate
          * based on opening the device successfully. */
         for( i=0; i < NUM_CUSTOMSAMPLINGRATES; i++ )
@@ -525,23 +376,22 @@ const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceID id )
     }
     sDevicePtrs[ id ] = deviceInfo;
     return deviceInfo;
-
 error:
-    PaHost_FreeTrackedMemory( sampleRates ); /* MEM */
-    PaHost_FreeTrackedMemory( deviceInfo ); /* MEM */
+    GlobalFree( sampleRates ); /* MEM */
+    GlobalFree( deviceInfo ); /* MEM */
 
     return NULL;
 }
 /*************************************************************************
- * Returns recommended device ID.
- * On the PC, the recommended device can be specified by the user 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 ID by using
- * the supplied application "pa_devs".
- */
+** Returns recommended device ID.
+** On the PC, the recommended device can be specified by the user 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 ID by using
+** the supplied application "pa_devs".
+*/
 #define PA_ENV_BUF_SIZE  (32)
 #define PA_REC_IN_DEV_ENV_NAME  ("PA_RECOMMENDED_INPUT_DEVICE")
 #define PA_REC_OUT_DEV_ENV_NAME  ("PA_RECOMMENDED_OUTPUT_DEVICE")
@@ -550,7 +400,6 @@ static PaDeviceID PaHost_GetEnvDefaultDeviceID( char *envName )
     DWORD   hresult;
     char    envbuf[PA_ENV_BUF_SIZE];
     PaDeviceID recommendedID = paNoDevice;
-
     /* Let user determine default device by setting environment variable. */
     hresult = GetEnvironmentVariable( envName, envbuf, PA_ENV_BUF_SIZE );
     if( (hresult > 0) && (hresult < PA_ENV_BUF_SIZE) )
@@ -559,69 +408,73 @@ static PaDeviceID PaHost_GetEnvDefaultDeviceID( char *envName )
     }
     return recommendedID;
 }
+static PaError Pa_MaybeQueryDevices( void )
+{
+    if( sNumDevices == 0 )
+    {
+        return Pa_QueryDevices();
+    }
+    return 0;
+}
 /**********************************************************************
- * Check for environment variable, else query devices and use result.
- */
+** Check for environment variable, else query devices and use result.
+*/
 PaDeviceID Pa_GetDefaultInputDeviceID( void )
 {
-    PaDeviceID result;
-
+    PaError result;
     result = PaHost_GetEnvDefaultDeviceID( PA_REC_IN_DEV_ENV_NAME );
-    if( result == paNoDevice || result < 0 || result >= sNumInputDevices )
+    if( result < 0 )
     {
+        result = Pa_MaybeQueryDevices();
+        if( result < 0 ) return result;
         result = sDefaultInputDeviceID;
     }
     return result;
 }
 PaDeviceID Pa_GetDefaultOutputDeviceID( void )
 {
-    PaDeviceID result;
-
+    PaError result;
     result = PaHost_GetEnvDefaultDeviceID( PA_REC_OUT_DEV_ENV_NAME );
-    if( result == paNoDevice || result < sNumInputDevices || result >= sNumDevices )
+    if( result < 0 )
     {
+        result = Pa_MaybeQueryDevices();
+        if( result < 0 ) return result;
         result = sDefaultOutputDeviceID;
     }
     return result;
 }
 /**********************************************************************
- * Initialize Host dependant part of API.
- */
+** Initialize Host dependant part of API.
+*/
 PaError PaHost_Init( void )
 {
-
-#if PA_TRACK_MEMORY
-    PRINT(("PaHost_Init: sNumAllocations = %d\n", sNumAllocations ));
-#endif
-
 #if PA_SIMULATE_UNDERFLOW
     PRINT(("WARNING - Underflow Simulation Enabled - Expect a Big Glitch!!!\n"));
 #endif
-   
-
-    Pa_InitializeNumDevices();
-
-    return Pa_AllocateDevicePtrs();
+    return Pa_MaybeQueryDevices();
 }
 
 /**********************************************************************
- * Check WAVE buffers to see if they are done.
- * Fill any available output buffers and use any available
- * input buffers by calling user callback.
- *
- * This routine will loop until:
- *    user callback returns !=0 OR
- *    all output buffers are filled OR
- *    past->past_StopSoon is set OR
- *    an error occurs when calling WMME.
- *
- * Returns >0 when user requests a stop, <0 on error.
- *
- */
-static PaError Pa_TimeSlice( internalPortAudioStream *stream )
+** Check WAVE buffers to see if they are done.
+** Fill any available output buffers and use any available
+** input buffers by calling user callback.
+**
+** This routine will loop until:
+**    user callback returns !=0 OR
+**    all output buffers are filled OR
+**    past->past_StopSoon is set OR
+**    an error occurs when calling WMME.
+**
+** Returns >0 when user requests a stop, <0 on error.
+**    
+*/
+static PaError Pa_TimeSlice( internalPortAudioStream   *past )
 {
-    PaError           result = paNoError;
-    MMRESULT          mmresult;
+    PaError           result = 0;
+    long              bytesEmpty = 0;
+    long              bytesFilled = 0;
+    long              buffersEmpty = 0;
+    MMRESULT          mresult;
     char             *inBufPtr;
     char             *outBufPtr;
     int               gotInput = 0;
@@ -629,18 +482,17 @@ static PaError Pa_TimeSlice( internalPortAudioStream *stream )
     int               i;
     int               buffersProcessed = 0;
     int               done = 0;
-    PaWMMEStreamData *wmmeStreamData = (PaWMMEStreamData *) stream->past_DeviceData;
-
-    if( wmmeStreamData == NULL ) return paInternalError;
+    PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;
+    if( pahsc == NULL ) return paInternalError;
 
-    stream->past_NumCallbacks += 1;
+    past->past_NumCallbacks += 1;
 #if PA_TRACE_RUN
-    AddTraceMessage("Pa_TimeSlice: past_NumCallbacks ", stream->past_NumCallbacks );
+    AddTraceMessage("Pa_TimeSlice: past_NumCallbacks ", past->past_NumCallbacks );
 #endif
 
     /* JM20020118 - prevent hung thread when buffers underflow. */
     /* while( !done ) /* BAD */
-    while( !done && !stream->past_StopSoon ) /* GOOD */
+    while( !done && !past->past_StopSoon ) /* GOOD */
     {
 #if PA_SIMULATE_UNDERFLOW
         if(gUnderCallbackCounter++ == UNDER_SLEEP_AT)
@@ -652,29 +504,29 @@ static PaError Pa_TimeSlice( internalPortAudioStream *stream )
         /* If we are using output, then we need an empty output buffer. */
         gotOutput = 0;
         outBufPtr = NULL;
-        if( stream->past_NumOutputChannels > 0 )
+        if( past->past_NumOutputChannels > 0 )
         {
-            if((wmmeStreamData->outputBuffers[ wmmeStreamData->currentOutputBuffer ].dwFlags & WHDR_DONE) == 0)
+            if((pahsc->pahsc_OutputBuffers[ pahsc->pahsc_CurrentOutputBuffer ].dwFlags & WHDR_DONE) == 0)
             {
                 break;  /* If none empty then bail and try again later. */
             }
             else
             {
-                outBufPtr = wmmeStreamData->outputBuffers[ wmmeStreamData->currentOutputBuffer ].lpData;
+                outBufPtr = pahsc->pahsc_OutputBuffers[ pahsc->pahsc_CurrentOutputBuffer ].lpData;
                 gotOutput = 1;
             }
         }
         /* Use an input buffer if one is available. */
         gotInput = 0;
         inBufPtr = NULL;
-        if( ( stream->past_NumInputChannels > 0 ) &&
-                (wmmeStreamData->inputBuffers[ wmmeStreamData->currentInputBuffer ].dwFlags & WHDR_DONE) )
+        if( ( past->past_NumInputChannels > 0 ) &&
+                (pahsc->pahsc_InputBuffers[ pahsc->pahsc_CurrentInputBuffer ].dwFlags & WHDR_DONE) )
         {
-            inBufPtr = wmmeStreamData->inputBuffers[ wmmeStreamData->currentInputBuffer ].lpData;
+            inBufPtr = pahsc->pahsc_InputBuffers[ pahsc->pahsc_CurrentInputBuffer ].lpData;
             gotInput = 1;
 #if PA_TRACE_RUN
             AddTraceMessage("Pa_TimeSlice: got input buffer at ", (int)inBufPtr );
-            AddTraceMessage("Pa_TimeSlice: got input buffer # ", wmmeStreamData->currentInputBuffer );
+            AddTraceMessage("Pa_TimeSlice: got input buffer # ", pahsc->pahsc_CurrentInputBuffer );
 #endif
 
         }
@@ -683,8 +535,8 @@ static PaError Pa_TimeSlice( internalPortAudioStream *stream )
         buffersProcessed += 1;
         /* Each Wave buffer contains multiple user buffers so do them all now. */
         /* Base Usage on time it took to process one host buffer. */
-        Pa_StartUsageCalculation( stream );
-        for( i=0; i<wmmeStreamData->userBuffersPerHostBuffer; i++ )
+        Pa_StartUsageCalculation( past );
+        for( i=0; i<pahsc->pahsc_UserBuffersPerHostBuffer; i++ )
         {
             if( done )
             {
@@ -692,51 +544,51 @@ static PaError Pa_TimeSlice( internalPortAudioStream *stream )
                 {
                     /* Clear remainder of wave buffer if we are waiting for stop. */
                     AddTraceMessage("Pa_TimeSlice: zero rest of wave buffer ", i );
-                    memset( outBufPtr, 0, wmmeStreamData->bytesPerUserOutputBuffer );
+                    memset( outBufPtr, 0, pahsc->pahsc_BytesPerUserOutputBuffer );
                 }
             }
             else
             {
                 /* Convert 16 bit native data to user data and call user routine. */
-                result = Pa_CallConvertInt16( stream, (short *) inBufPtr, (short *) outBufPtr );
+                result = Pa_CallConvertInt16( past, (short *) inBufPtr, (short *) outBufPtr );
                 if( result != 0) done = 1;
             }
-            if( gotInput ) inBufPtr += wmmeStreamData->bytesPerUserInputBuffer;
-            if( gotOutput) outBufPtr += wmmeStreamData->bytesPerUserOutputBuffer;
+            if( gotInput ) inBufPtr += pahsc->pahsc_BytesPerUserInputBuffer;
+            if( gotOutput) outBufPtr += pahsc->pahsc_BytesPerUserOutputBuffer;
         }
-        Pa_EndUsageCalculation( stream );
+        Pa_EndUsageCalculation( past );
         /* Send WAVE buffer to Wave Device to be refilled. */
         if( gotInput )
         {
-            mmresult = waveInAddBuffer( wmmeStreamData->hWaveIn,
-                                       &wmmeStreamData->inputBuffers[ wmmeStreamData->currentInputBuffer ],
+            mresult = waveInAddBuffer( pahsc->pahsc_HWaveIn,
+                                       &pahsc->pahsc_InputBuffers[ pahsc->pahsc_CurrentInputBuffer ],
                                        sizeof(WAVEHDR) );
-            if( mmresult != MMSYSERR_NOERROR )
+            if( mresult != MMSYSERR_NOERROR )
             {
-                sPaHostError = mmresult;
+                sPaHostError = mresult;
                 result = paHostError;
                 break;
             }
-            wmmeStreamData->currentInputBuffer = (wmmeStreamData->currentInputBuffer+1 >= wmmeStreamData->numHostBuffers) ?
-                                              0 : wmmeStreamData->currentInputBuffer+1;
+            pahsc->pahsc_CurrentInputBuffer = (pahsc->pahsc_CurrentInputBuffer+1 >= pahsc->pahsc_NumHostBuffers) ?
+                                              0 : pahsc->pahsc_CurrentInputBuffer+1;
         }
         /* Write WAVE buffer to Wave Device. */
         if( gotOutput )
         {
 #if PA_TRACE_START_STOP
-            AddTraceMessage( "Pa_TimeSlice: writing buffer ", wmmeStreamData->currentOutputBuffer );
+            AddTraceMessage( "Pa_TimeSlice: writing buffer ", pahsc->pahsc_CurrentOutputBuffer );
 #endif
-            mmresult = waveOutWrite( wmmeStreamData->hWaveOut,
-                                    &wmmeStreamData->outputBuffers[ wmmeStreamData->currentOutputBuffer ],
+            mresult = waveOutWrite( pahsc->pahsc_HWaveOut,
+                                    &pahsc->pahsc_OutputBuffers[ pahsc->pahsc_CurrentOutputBuffer ],
                                     sizeof(WAVEHDR) );
-            if( mmresult != MMSYSERR_NOERROR )
+            if( mresult != MMSYSERR_NOERROR )
             {
-                sPaHostError = mmresult;
+                sPaHostError = mresult;
                 result = paHostError;
                 break;
             }
-            wmmeStreamData->currentOutputBuffer = (wmmeStreamData->currentOutputBuffer+1 >= wmmeStreamData->numHostBuffers) ?
-                                               0 : wmmeStreamData->currentOutputBuffer+1;
+            pahsc->pahsc_CurrentOutputBuffer = (pahsc->pahsc_CurrentOutputBuffer+1 >= pahsc->pahsc_NumHostBuffers) ?
+                                               0 : pahsc->pahsc_CurrentOutputBuffer+1;
         }
 
     }
@@ -748,62 +600,62 @@ static PaError Pa_TimeSlice( internalPortAudioStream *stream )
 }
 
 /*******************************************************************/
-static PaError PaHost_BackgroundManager( internalPortAudioStream *stream )
+static PaError PaHost_BackgroundManager( internalPortAudioStream   *past )
 {
-    PaError      result = paNoError;
+    PaError      result = 0;
     int          i;
-    int          numQueuedoutputBuffers = 0;
-    PaWMMEStreamData *wmmeStreamData = (PaWMMEStreamData *) stream->past_DeviceData;
+    int          numQueuedOutputBuffers = 0;
+    PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;
 
     /* Has someone asked us to abort by calling Pa_AbortStream()? */
-    if( stream->past_StopNow )
+    if( past->past_StopNow )
     {
-        stream->past_IsActive = 0; /* Will cause thread to return. */
+        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( stream->past_StopSoon )
+    else if( past->past_StopSoon )
     {
         /* Poll buffer and when all have played then exit thread. */
         /* Count how many output buffers are queued. */
-        numQueuedoutputBuffers = 0;
-        if( stream->past_NumOutputChannels > 0 )
+        numQueuedOutputBuffers = 0;
+        if( past->past_NumOutputChannels > 0 )
         {
-            for( i=0; i<wmmeStreamData->numHostBuffers; i++ )
+            for( i=0; i<pahsc->pahsc_NumHostBuffers; i++ )
             {
-                if( !( wmmeStreamData->outputBuffers[ i ].dwFlags & WHDR_DONE) )
+                if( !( pahsc->pahsc_OutputBuffers[ i ].dwFlags & WHDR_DONE) )
                 {
 #if PA_TRACE_START_STOP
-                    AddTraceMessage( "PaHost_BackgroundManager: waiting for buffer ", i );
+                    AddTraceMessage( "WinMMPa_OutputThreadProc: waiting for buffer ", i );
 #endif
-                    numQueuedoutputBuffers++;
+                    numQueuedOutputBuffers++;
                 }
             }
         }
 #if PA_TRACE_START_STOP
-        AddTraceMessage( "PaHost_BackgroundManager: numQueuedoutputBuffers ", numQueuedoutputBuffers );
+        AddTraceMessage( "WinMMPa_OutputThreadProc: numQueuedOutputBuffers ", numQueuedOutputBuffers );
 #endif
-        if( numQueuedoutputBuffers == 0 )
+        if( numQueuedOutputBuffers == 0 )
         {
-            stream->past_IsActive = 0; /* Will cause thread to return. */
+            past->past_IsActive = 0; /* Will cause thread to return. */
         }
     }
     else
     {
         /* Process full input buffer and fill up empty output buffers. */
-        if( (result = Pa_TimeSlice( stream )) != 0)
+        if( (result = Pa_TimeSlice( past )) != 0)
         {
             /* User callback has asked us to stop. */
 #if PA_TRACE_START_STOP
-            AddTraceMessage( "PaHost_BackgroundManager: TimeSlice() returned ", result );
+            AddTraceMessage( "WinMMPa_OutputThreadProc: TimeSlice() returned ", result );
 #endif
-            stream->past_StopSoon = 1; /* Request that audio play out then stop. */
+            past->past_StopSoon = 1; /* Request that audio play out then stop. */
             result = paNoError;
         }
     }
 
-    PaHost_UpdateStreamTime( wmmeStreamData );
+    PaHost_UpdateStreamTime( pahsc );
     return result;
 }
 
@@ -811,57 +663,57 @@ static PaError PaHost_BackgroundManager( internalPortAudioStream *stream )
 /*******************************************************************/
 static void CALLBACK Pa_TimerCallback(UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2)
 {
-    internalPortAudioStream   *stream;
-    PaWMMEStreamData        *wmmeStreamData;
+    internalPortAudioStream   *past;
+    PaHostSoundControl        *pahsc;
     PaError                    result;
-
-    stream = (internalPortAudioStream *) dwUser;
-    if( stream == NULL ) return;
-    wmmeStreamData = (PaWMMEStreamData *) stream->past_DeviceData;
-    if( wmmeStreamData == NULL ) return;
-    if( wmmeStreamData->ifInsideCallback )
+    past = (internalPortAudioStream *) dwUser;
+    if( past == NULL ) return;
+    pahsc = (PaHostSoundControl *) past->past_DeviceData;
+    if( pahsc == NULL ) return;
+    if( pahsc->pahsc_IfInsideCallback )
     {
-        if( wmmeStreamData->timerID != 0 )
+        if( pahsc->pahsc_TimerID != 0 )
         {
-            timeKillEvent(wmmeStreamData->timerID);  /* Stop callback timer. */
-            wmmeStreamData->timerID = 0;
+            timeKillEvent(pahsc->pahsc_TimerID);  /* Stop callback timer. */
+            pahsc->pahsc_TimerID = 0;
         }
         return;
     }
-    wmmeStreamData->ifInsideCallback = 1;
+    pahsc->pahsc_IfInsideCallback = 1;
     /* Manage flags and audio processing. */
-    result = PaHost_BackgroundManager( stream );
+    result = PaHost_BackgroundManager( past );
     if( result != paNoError )
     {
-        stream->past_IsActive = 0;
+        past->past_IsActive = 0;
     }
-    wmmeStreamData->ifInsideCallback = 0;
+    pahsc->pahsc_IfInsideCallback = 0;
 }
 #else /* PA_USE_TIMER_CALLBACK */
 /*******************************************************************/
 static DWORD WINAPI WinMMPa_OutputThreadProc( void *pArg )
 {
-    internalPortAudioStream *stream;
-    PaWMMEStreamData      *wmmeStreamData;
+    internalPortAudioStream *past;
+    PaHostSoundControl      *pahsc;
+    void        *inputBuffer=NULL;
     HANDLE       events[2];
     int          numEvents = 0;
     DWORD        result = 0;
     DWORD        waitResult;
     DWORD        numTimeouts = 0;
     DWORD        timeOut;
-    stream = (internalPortAudioStream *) pArg;
-    wmmeStreamData = (PaWMMEStreamData *) stream->past_DeviceData;
+    past = (internalPortAudioStream *) pArg;
+    pahsc = (PaHostSoundControl *) past->past_DeviceData;
 #if PA_TRACE_START_STOP
     AddTraceMessage( "WinMMPa_OutputThreadProc: timeoutPeriod", timeoutPeriod );
-    AddTraceMessage( "WinMMPa_OutputThreadProc: past_NumUserBuffers", stream->past_NumUserBuffers );
+    AddTraceMessage( "WinMMPa_OutputThreadProc: past_NumUserBuffers", past->past_NumUserBuffers );
 #endif
     /* Calculate timeOut as half the time it would take to play all buffers. */
-    timeOut = (DWORD) (500.0 * PaHost_GetTotalBufferFrames( stream ) / stream->past_SampleRate);
+    timeOut = (DWORD) (500.0 * PaHost_GetTotalBufferFrames( past ) / past->past_SampleRate);
     /* Get event(s) ready for wait. */
-    events[numEvents++] = wmmeStreamData->bufferEvent;
-    if( wmmeStreamData->abortEventInited ) events[numEvents++] = wmmeStreamData->abortEvent;
+    events[numEvents++] = pahsc->pahsc_BufferEvent;
+    if( pahsc->pahsc_AbortEventInited ) events[numEvents++] = pahsc->pahsc_AbortEvent;
     /* Stay in this thread as long as we are "active". */
-    while( stream->past_IsActive )
+    while( past->past_IsActive )
     {
         /*******************************************************************/
         /******** WAIT here for an event from WMME or PA *******************/
@@ -872,21 +724,21 @@ static DWORD WINAPI WinMMPa_OutputThreadProc( void *pArg )
         {
             sPaHostError = GetLastError();
             result = paHostError;
-            stream->past_IsActive = 0;
+            past->past_IsActive = 0;
         }
         /* Timeout? Don't stop. Just keep polling for DONE.*/
         else if( waitResult == WAIT_TIMEOUT )
         {
 #if PA_TRACE_START_STOP
-            AddTraceMessage( "WinMMPa_OutputThreadProc: timed out ", numQueuedoutputBuffers );
+            AddTraceMessage( "WinMMPa_OutputThreadProc: timed out ", numQueuedOutputBuffers );
 #endif
             numTimeouts += 1;
         }
         /* Manage flags and audio processing. */
-        result = PaHost_BackgroundManager( stream );
+        result = PaHost_BackgroundManager( past );
         if( result != paNoError )
         {
-            stream->past_IsActive = 0;
+            past->past_IsActive = 0;
         }
     }
     return result;
@@ -894,218 +746,210 @@ static DWORD WINAPI WinMMPa_OutputThreadProc( void *pArg )
 #endif
 
 /*******************************************************************/
-PaError PaHost_OpenInputStream( internalPortAudioStream   *stream )
+PaError PaHost_OpenInputStream( internalPortAudioStream   *past )
 {
+    MMRESULT         mr;
     PaError          result = paNoError;
-    MMRESULT         mmresult;
-    PaWMMEStreamData *wmmeStreamData;
+    PaHostSoundControl *pahsc;
     int              i;
     int              inputMmId;
     int              bytesPerInputFrame;
     WAVEFORMATEX     wfx;
-    const PaDeviceInfo  *deviceInfo;
-
-    wmmeStreamData = (PaWMMEStreamData *) stream->past_DeviceData;
-    DBUG(("PaHost_OpenStream: deviceID = 0x%x\n", stream->past_InputDeviceID));
-    deviceInfo = Pa_GetDeviceInfo( stream->past_InputDeviceID );
-    if( deviceInfo == NULL ) return paInternalError;
-
-    switch( deviceInfo->nativeSampleFormats  )
+    const PaDeviceInfo  *pad;
+    pahsc = (PaHostSoundControl *) past->past_DeviceData;
+    DBUG(("PaHost_OpenStream: deviceID = 0x%x\n", past->past_InputDeviceID));
+    pad = Pa_GetDeviceInfo( past->past_InputDeviceID );
+    if( pad == NULL ) return paInternalError;
+    switch( pad->nativeSampleFormats  )
     {
     case paInt32:
     case paFloat32:
-        bytesPerInputFrame = sizeof(float) * stream->past_NumInputChannels;
+        bytesPerInputFrame = sizeof(float) * past->past_NumInputChannels;
         break;
     default:
-        bytesPerInputFrame = sizeof(short) * stream->past_NumInputChannels;
+        bytesPerInputFrame = sizeof(short) * past->past_NumInputChannels;
         break;
     }
     wfx.wFormatTag = WAVE_FORMAT_PCM;
-    wfx.nChannels = (WORD) stream->past_NumInputChannels;
-    wfx.nSamplesPerSec = (DWORD) stream->past_SampleRate;
-    wfx.nAvgBytesPerSec = (DWORD)(bytesPerInputFrame * stream->past_SampleRate);
+    wfx.nChannels = (WORD) past->past_NumInputChannels;
+    wfx.nSamplesPerSec = (DWORD) past->past_SampleRate;
+    wfx.nAvgBytesPerSec = (DWORD)(bytesPerInputFrame * past->past_SampleRate);
     wfx.nBlockAlign = (WORD)bytesPerInputFrame;
-    wfx.wBitsPerSample = (WORD)((bytesPerInputFrame/stream->past_NumInputChannels) * 8);
+    wfx.wBitsPerSample = (WORD)((bytesPerInputFrame/past->past_NumInputChannels) * 8);
     wfx.cbSize = 0;
-    inputMmId = PaDeviceIdToWinId( stream->past_InputDeviceID );
+    inputMmId = PaDeviceIdToWinId( past->past_InputDeviceID );
 #if PA_USE_TIMER_CALLBACK
-    mmresult = waveInOpen( &wmmeStreamData->hWaveIn, inputMmId, &wfx,
+    mr = waveInOpen( &pahsc->pahsc_HWaveIn, inputMmId, &wfx,
                      0, 0, CALLBACK_NULL );
 #else
-    mmresult = waveInOpen( &wmmeStreamData->hWaveIn, inputMmId, &wfx,
-                     (DWORD)wmmeStreamData->bufferEvent, (DWORD) stream, CALLBACK_EVENT );
+    mr = waveInOpen( &pahsc->pahsc_HWaveIn, inputMmId, &wfx,
+                     (DWORD)pahsc->pahsc_BufferEvent, (DWORD) past, CALLBACK_EVENT );
 #endif
-    if( mmresult != MMSYSERR_NOERROR )
+    if( mr != MMSYSERR_NOERROR )
     {
         ERR_RPT(("PortAudio: PaHost_OpenInputStream() failed!\n"));
         result = paHostError;
-        sPaHostError = mmresult;
+        sPaHostError = mr;
         goto error;
     }
     /* Allocate an array to hold the buffer pointers. */
-    wmmeStreamData->inputBuffers = (WAVEHDR *) PaHost_AllocateTrackedMemory( sizeof(WAVEHDR)*wmmeStreamData->numHostBuffers ); /* MEM */
-    if( wmmeStreamData->inputBuffers == NULL )
+    pahsc->pahsc_InputBuffers = (WAVEHDR *) GlobalAlloc( GMEM_FIXED | GMEM_ZEROINIT, sizeof(WAVEHDR)*pahsc->pahsc_NumHostBuffers ); /* MEM */
+    if( pahsc->pahsc_InputBuffers == NULL )
     {
         result = paInsufficientMemory;
         goto error;
     }
     /* Allocate each buffer. */
-    for( i=0; i<wmmeStreamData->numHostBuffers; i++ )
+    for( i=0; i<pahsc->pahsc_NumHostBuffers; i++ )
     {
-        wmmeStreamData->inputBuffers[i].lpData = (char *)PaHost_AllocateTrackedMemory( wmmeStreamData->bytesPerHostInputBuffer ); /* MEM */
-        if( wmmeStreamData->inputBuffers[i].lpData == NULL )
+        pahsc->pahsc_InputBuffers[i].lpData = (char *)GlobalAlloc( GMEM_FIXED, pahsc->pahsc_BytesPerHostInputBuffer ); /* MEM */
+        if( pahsc->pahsc_InputBuffers[i].lpData == NULL )
         {
             result = paInsufficientMemory;
             goto error;
         }
-        wmmeStreamData->inputBuffers[i].dwBufferLength = wmmeStreamData->bytesPerHostInputBuffer;
-        wmmeStreamData->inputBuffers[i].dwUser = i;
-        if( ( mmresult = waveInPrepareHeader( wmmeStreamData->hWaveIn, &wmmeStreamData->inputBuffers[i], sizeof(WAVEHDR) )) != MMSYSERR_NOERROR )
+        pahsc->pahsc_InputBuffers[i].dwBufferLength = pahsc->pahsc_BytesPerHostInputBuffer;
+        pahsc->pahsc_InputBuffers[i].dwUser = i;
+        if( ( mr = waveInPrepareHeader( pahsc->pahsc_HWaveIn, &pahsc->pahsc_InputBuffers[i], sizeof(WAVEHDR) )) != MMSYSERR_NOERROR )
         {
             result = paHostError;
-            sPaHostError = mmresult;
+            sPaHostError = mr;
             goto error;
         }
     }
     return result;
-
 error:
     return result;
 }
 /*******************************************************************/
-PaError PaHost_OpenOutputStream( internalPortAudioStream *stream )
+PaError PaHost_OpenOutputStream( internalPortAudioStream   *past )
 {
+    MMRESULT         mr;
     PaError          result = paNoError;
-    MMRESULT         mmresult;
-    PaWMMEStreamData *wmmeStreamData;
+    PaHostSoundControl *pahsc;
     int              i;
     int              outputMmID;
     int              bytesPerOutputFrame;
     WAVEFORMATEX     wfx;
-    const PaDeviceInfo *deviceInfo;
-
-    wmmeStreamData = (PaWMMEStreamData *) stream->past_DeviceData;
-    DBUG(("PaHost_OpenStream: deviceID = 0x%x\n", stream->past_OutputDeviceID));
-
-    deviceInfo = Pa_GetDeviceInfo( stream->past_OutputDeviceID );
-    if( deviceInfo == NULL ) return paInternalError;
-
-    switch( deviceInfo->nativeSampleFormats  )
+    const PaDeviceInfo *pad;
+    pahsc = (PaHostSoundControl *) past->past_DeviceData;
+    DBUG(("PaHost_OpenStream: deviceID = 0x%x\n", past->past_OutputDeviceID));
+    pad = Pa_GetDeviceInfo( past->past_OutputDeviceID );
+    if( pad == NULL ) return paInternalError;
+    switch( pad->nativeSampleFormats  )
     {
     case paInt32:
     case paFloat32:
-        bytesPerOutputFrame = sizeof(float) * stream->past_NumOutputChannels;
+        bytesPerOutputFrame = sizeof(float) * past->past_NumOutputChannels;
         break;
     default:
-        bytesPerOutputFrame = sizeof(short) * stream->past_NumOutputChannels;
+        bytesPerOutputFrame = sizeof(short) * past->past_NumOutputChannels;
         break;
     }
     wfx.wFormatTag = WAVE_FORMAT_PCM;
-    wfx.nChannels = (WORD) stream->past_NumOutputChannels;
-    wfx.nSamplesPerSec = (DWORD) stream->past_SampleRate;
-    wfx.nAvgBytesPerSec = (DWORD)(bytesPerOutputFrame * stream->past_SampleRate);
+    wfx.nChannels = (WORD) past->past_NumOutputChannels;
+    wfx.nSamplesPerSec = (DWORD) past->past_SampleRate;
+    wfx.nAvgBytesPerSec = (DWORD)(bytesPerOutputFrame * past->past_SampleRate);
     wfx.nBlockAlign = (WORD)bytesPerOutputFrame;
-    wfx.wBitsPerSample = (WORD)((bytesPerOutputFrame/stream->past_NumOutputChannels) * 8);
+    wfx.wBitsPerSample = (WORD)((bytesPerOutputFrame/past->past_NumOutputChannels) * 8);
     wfx.cbSize = 0;
-    outputMmID = PaDeviceIdToWinId( stream->past_OutputDeviceID );
+    outputMmID = PaDeviceIdToWinId( past->past_OutputDeviceID );
 #if PA_USE_TIMER_CALLBACK
-    mmresult = waveOutOpen( &wmmeStreamData->hWaveOut, outputMmID, &wfx,
+    mr = waveOutOpen( &pahsc->pahsc_HWaveOut, outputMmID, &wfx,
                       0, 0, CALLBACK_NULL );
 #else
 
-    wmmeStreamData->abortEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
-    if( wmmeStreamData->abortEvent == NULL )
+    pahsc->pahsc_AbortEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
+    if( pahsc->pahsc_AbortEvent == NULL )
     {
         result = paHostError;
         sPaHostError = GetLastError();
         goto error;
     }
-    wmmeStreamData->abortEventInited = 1;
-    mmresult = waveOutOpen( &wmmeStreamData->hWaveOut, outputMmID, &wfx,
-                      (DWORD)wmmeStreamData->bufferEvent, (DWORD) stream, CALLBACK_EVENT );
+    pahsc->pahsc_AbortEventInited = 1;
+    mr = waveOutOpen( &pahsc->pahsc_HWaveOut, outputMmID, &wfx,
+                      (DWORD)pahsc->pahsc_BufferEvent, (DWORD) past, CALLBACK_EVENT );
 #endif
-    if( mmresult != MMSYSERR_NOERROR )
+    if( mr != MMSYSERR_NOERROR )
     {
         ERR_RPT(("PortAudio: PaHost_OpenOutputStream() failed!\n"));
         result = paHostError;
-        sPaHostError = mmresult;
+        sPaHostError = mr;
         goto error;
     }
     /* Allocate an array to hold the buffer pointers. */
-    wmmeStreamData->outputBuffers = (WAVEHDR *) PaHost_AllocateTrackedMemory( sizeof(WAVEHDR)*wmmeStreamData->numHostBuffers ); /* MEM */
-    if( wmmeStreamData->outputBuffers == NULL )
+    pahsc->pahsc_OutputBuffers = (WAVEHDR *) GlobalAlloc( GMEM_FIXED | GMEM_ZEROINIT, sizeof(WAVEHDR)*pahsc->pahsc_NumHostBuffers ); /* MEM */
+    if( pahsc->pahsc_OutputBuffers == NULL )
     {
         result = paInsufficientMemory;
         goto error;
     }
     /* Allocate each buffer. */
-    for( i=0; i<wmmeStreamData->numHostBuffers; i++ )
+    for( i=0; i<pahsc->pahsc_NumHostBuffers; i++ )
     {
-        wmmeStreamData->outputBuffers[i].lpData = (char *) PaHost_AllocateTrackedMemory( wmmeStreamData->bytesPerHostOutputBuffer ); /* MEM */
-        if( wmmeStreamData->outputBuffers[i].lpData == NULL )
+        pahsc->pahsc_OutputBuffers[i].lpData = (char *) GlobalAlloc( GMEM_FIXED, pahsc->pahsc_BytesPerHostOutputBuffer ); /* MEM */
+        if( pahsc->pahsc_OutputBuffers[i].lpData == NULL )
         {
             result = paInsufficientMemory;
             goto error;
         }
-        wmmeStreamData->outputBuffers[i].dwBufferLength = wmmeStreamData->bytesPerHostOutputBuffer;
-        wmmeStreamData->outputBuffers[i].dwUser = i;
-        if( (mmresult = waveOutPrepareHeader( wmmeStreamData->hWaveOut, &wmmeStreamData->outputBuffers[i], sizeof(WAVEHDR) )) != MMSYSERR_NOERROR )
+        pahsc->pahsc_OutputBuffers[i].dwBufferLength = pahsc->pahsc_BytesPerHostOutputBuffer;
+        pahsc->pahsc_OutputBuffers[i].dwUser = i;
+        if( (mr = waveOutPrepareHeader( pahsc->pahsc_HWaveOut, &pahsc->pahsc_OutputBuffers[i], sizeof(WAVEHDR) )) != MMSYSERR_NOERROR )
         {
             result = paHostError;
-            sPaHostError = mmresult;
+            sPaHostError = mr;
             goto error;
         }
     }
     return result;
-
 error:
     return result;
 }
 /*******************************************************************/
-PaError PaHost_GetTotalBufferFrames( internalPortAudioStream *stream )
+PaError PaHost_GetTotalBufferFrames( internalPortAudioStream   *past )
 {
-    PaWMMEStreamData *wmmeStreamData = (PaWMMEStreamData *) stream->past_DeviceData;
-    return wmmeStreamData->numHostBuffers * wmmeStreamData->framesPerHostBuffer;
+    PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;
+    return pahsc->pahsc_NumHostBuffers * pahsc->pahsc_FramesPerHostBuffer;
 }
 /*******************************************************************
- * Determine number of WAVE Buffers
- * and how many User Buffers we can put into each WAVE buffer.
- */
-static void PaHost_CalcNumHostBuffers( internalPortAudioStream *stream )
+* Determine number of WAVE Buffers
+* and how many User Buffers we can put into each WAVE buffer.
+*/
+static void PaHost_CalcNumHostBuffers( internalPortAudioStream *past )
 {
-    PaWMMEStreamData *wmmeStreamData = (PaWMMEStreamData *) stream->past_DeviceData;
+    PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;
     unsigned int  minNumBuffers;
-    int           minframesPerHostBuffer;
-    int           maxframesPerHostBuffer;
+    int           minFramesPerHostBuffer;
+    int           maxFramesPerHostBuffer;
     int           minTotalFrames;
     int           userBuffersPerHostBuffer;
     int           framesPerHostBuffer;
     int           numHostBuffers;
-
     /* Calculate minimum and maximum sizes based on timing and sample rate. */
-    minframesPerHostBuffer = (int) (PA_MIN_MSEC_PER_HOST_BUFFER * stream->past_SampleRate * 0.001);
-    minframesPerHostBuffer = (minframesPerHostBuffer + 7) & ~7;
-    DBUG(("PaHost_CalcNumHostBuffers: minframesPerHostBuffer = %d\n", minframesPerHostBuffer ));
-    maxframesPerHostBuffer = (int) (PA_MAX_MSEC_PER_HOST_BUFFER * stream->past_SampleRate * 0.001);
-    maxframesPerHostBuffer = (maxframesPerHostBuffer + 7) & ~7;
-    DBUG(("PaHost_CalcNumHostBuffers: maxframesPerHostBuffer = %d\n", maxframesPerHostBuffer ));
+    minFramesPerHostBuffer = (int) (PA_MIN_MSEC_PER_HOST_BUFFER * past->past_SampleRate / 1000.0);
+    minFramesPerHostBuffer = (minFramesPerHostBuffer + 7) & ~7;
+    DBUG(("PaHost_CalcNumHostBuffers: minFramesPerHostBuffer = %d\n", minFramesPerHostBuffer ));
+    maxFramesPerHostBuffer = (int) (PA_MAX_MSEC_PER_HOST_BUFFER * past->past_SampleRate / 1000.0);
+    maxFramesPerHostBuffer = (maxFramesPerHostBuffer + 7) & ~7;
+    DBUG(("PaHost_CalcNumHostBuffers: maxFramesPerHostBuffer = %d\n", maxFramesPerHostBuffer ));
     /* Determine number of user buffers based on minimum latency. */
-    minNumBuffers = Pa_GetMinNumBuffers( stream->past_FramesPerUserBuffer, stream->past_SampleRate );
-    stream->past_NumUserBuffers = ( minNumBuffers > stream->past_NumUserBuffers ) ? minNumBuffers : stream->past_NumUserBuffers;
-    DBUG(("PaHost_CalcNumHostBuffers: min past_NumUserBuffers = %d\n", stream->past_NumUserBuffers ));
-    minTotalFrames = stream->past_NumUserBuffers * stream->past_FramesPerUserBuffer;
+    minNumBuffers = Pa_GetMinNumBuffers( 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 WAVE buffers too small because they may not get serviced quickly enough. */
-    if( (int) stream->past_FramesPerUserBuffer < minframesPerHostBuffer )
+    if( (int) past->past_FramesPerUserBuffer < minFramesPerHostBuffer )
     {
         userBuffersPerHostBuffer =
-            (minframesPerHostBuffer + stream->past_FramesPerUserBuffer - 1) /
-            stream->past_FramesPerUserBuffer;
+            (minFramesPerHostBuffer + past->past_FramesPerUserBuffer - 1) /
+            past->past_FramesPerUserBuffer;
     }
     else
     {
         userBuffersPerHostBuffer = 1;
     }
-    framesPerHostBuffer = stream->past_FramesPerUserBuffer * userBuffersPerHostBuffer;
+    framesPerHostBuffer = past->past_FramesPerUserBuffer * userBuffersPerHostBuffer;
     /* Calculate number of WAVE buffers needed. Round up to cover minTotalFrames. */
     numHostBuffers = (minTotalFrames + framesPerHostBuffer - 1) / framesPerHostBuffer;
     /* Make sure we have anough WAVE buffers. */
@@ -1114,446 +958,429 @@ static void PaHost_CalcNumHostBuffers( internalPortAudioStream *stream )
         numHostBuffers = PA_MIN_NUM_HOST_BUFFERS;
     }
     else if( (numHostBuffers > PA_MAX_NUM_HOST_BUFFERS) &&
-             ((int) stream->past_FramesPerUserBuffer < (maxframesPerHostBuffer/2) ) )
+             ((int) past->past_FramesPerUserBuffer < (maxFramesPerHostBuffer/2) ) )
     {
         /* If we have too many WAVE buffers, try to put more user buffers in a wave buffer. */
         while(numHostBuffers > PA_MAX_NUM_HOST_BUFFERS)
         {
             userBuffersPerHostBuffer += 1;
-            framesPerHostBuffer = stream->past_FramesPerUserBuffer * userBuffersPerHostBuffer;
+            framesPerHostBuffer = past->past_FramesPerUserBuffer * userBuffersPerHostBuffer;
             numHostBuffers = (minTotalFrames + framesPerHostBuffer - 1) / framesPerHostBuffer;
             /* If we have gone too far, back up one. */
-            if( (framesPerHostBuffer > maxframesPerHostBuffer) ||
+            if( (framesPerHostBuffer > maxFramesPerHostBuffer) ||
                     (numHostBuffers < PA_MAX_NUM_HOST_BUFFERS) )
             {
                 userBuffersPerHostBuffer -= 1;
-                framesPerHostBuffer = stream->past_FramesPerUserBuffer * userBuffersPerHostBuffer;
+                framesPerHostBuffer = past->past_FramesPerUserBuffer * userBuffersPerHostBuffer;
                 numHostBuffers = (minTotalFrames + framesPerHostBuffer - 1) / framesPerHostBuffer;
                 break;
             }
         }
     }
 
-    wmmeStreamData->userBuffersPerHostBuffer = userBuffersPerHostBuffer;
-    wmmeStreamData->framesPerHostBuffer = framesPerHostBuffer;
-    wmmeStreamData->numHostBuffers = numHostBuffers;
-    DBUG(("PaHost_CalcNumHostBuffers: userBuffersPerHostBuffer = %d\n", wmmeStreamData->userBuffersPerHostBuffer ));
-    DBUG(("PaHost_CalcNumHostBuffers: numHostBuffers = %d\n", wmmeStreamData->numHostBuffers ));
-    DBUG(("PaHost_CalcNumHostBuffers: framesPerHostBuffer = %d\n", wmmeStreamData->framesPerHostBuffer ));
-    DBUG(("PaHost_CalcNumHostBuffers: past_NumUserBuffers = %d\n", stream->past_NumUserBuffers ));
+    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 *stream )
+PaError PaHost_OpenStream( internalPortAudioStream   *past )
 {
     PaError             result = paNoError;
-    PaWMMEStreamData *wmmeStreamData;
-
-    result = PaHost_AllocateWMMEStreamData( stream );
-    if( result != paNoError ) return result;
-
-    wmmeStreamData = PaHost_GetWMMEStreamData( stream );
-
+    PaHostSoundControl *pahsc;
+    /* Allocate and initialize host data. */
+    pahsc = (PaHostSoundControl *) PaHost_AllocateFastMemory(sizeof(PaHostSoundControl)); /* MEM */
+    if( pahsc == NULL )
+    {
+        result = paInsufficientMemory;
+        goto error;
+    }
+    memset( pahsc, 0, sizeof(PaHostSoundControl) );
+    past->past_DeviceData = (void *) pahsc;
     /* Figure out how user buffers fit into WAVE buffers. */
-    PaHost_CalcNumHostBuffers( stream );
+    PaHost_CalcNumHostBuffers( past );
     {
-        int msecLatency = (int) ((PaHost_GetTotalBufferFrames(stream) * 1000) / stream->past_SampleRate);
-        DBUG(("PortAudio on WMME - Latency = %d frames, %d msec\n", PaHost_GetTotalBufferFrames(stream), msecLatency ));
+        int msecLatency = (int) ((PaHost_GetTotalBufferFrames(past) * 1000) / past->past_SampleRate);
+        DBUG(("PortAudio on WMME - Latency = %d frames, %d msec\n", PaHost_GetTotalBufferFrames(past), msecLatency ));
     }
-    InitializeCriticalSection( &wmmeStreamData->streamLock );
-    wmmeStreamData->streamLockInited = 1;
+    InitializeCriticalSection( &pahsc->pahsc_StreamLock );
+    pahsc->pahsc_StreamLockInited = 1;
 
 #if (PA_USE_TIMER_CALLBACK == 0)
-    wmmeStreamData->bufferEventInited = 0;
-    wmmeStreamData->bufferEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
-    if( wmmeStreamData->bufferEvent == NULL )
+    pahsc->pahsc_BufferEventInited = 0;
+    pahsc->pahsc_BufferEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
+    if( pahsc->pahsc_BufferEvent == NULL )
     {
         result = paHostError;
         sPaHostError = GetLastError();
         goto error;
     }
-    wmmeStreamData->bufferEventInited = 1;
+    pahsc->pahsc_BufferEventInited = 1;
 #endif /* (PA_USE_TIMER_CALLBACK == 0) */
     /* ------------------ OUTPUT */
-    wmmeStreamData->bytesPerUserOutputBuffer = stream->past_FramesPerUserBuffer * stream->past_NumOutputChannels * sizeof(short);
-    wmmeStreamData->bytesPerHostOutputBuffer = wmmeStreamData->userBuffersPerHostBuffer * wmmeStreamData->bytesPerUserOutputBuffer;
-    if( (stream->past_OutputDeviceID != paNoDevice) && (stream->past_NumOutputChannels > 0) )
+    pahsc->pahsc_BytesPerUserOutputBuffer = past->past_FramesPerUserBuffer * past->past_NumOutputChannels * sizeof(short);
+    pahsc->pahsc_BytesPerHostOutputBuffer = pahsc->pahsc_UserBuffersPerHostBuffer * pahsc->pahsc_BytesPerUserOutputBuffer;
+    if( (past->past_OutputDeviceID != paNoDevice) && (past->past_NumOutputChannels > 0) )
     {
-        result = PaHost_OpenOutputStream( stream );
+        result = PaHost_OpenOutputStream( past );
         if( result < 0 ) goto error;
     }
     /* ------------------ INPUT */
-    wmmeStreamData->bytesPerUserInputBuffer = stream->past_FramesPerUserBuffer * stream->past_NumInputChannels * sizeof(short);
-    wmmeStreamData->bytesPerHostInputBuffer = wmmeStreamData->userBuffersPerHostBuffer * wmmeStreamData->bytesPerUserInputBuffer;
-    if( (stream->past_InputDeviceID != paNoDevice) && (stream->past_NumInputChannels > 0) )
+    pahsc->pahsc_BytesPerUserInputBuffer = past->past_FramesPerUserBuffer * past->past_NumInputChannels * sizeof(short);
+    pahsc->pahsc_BytesPerHostInputBuffer = pahsc->pahsc_UserBuffersPerHostBuffer * pahsc->pahsc_BytesPerUserInputBuffer;
+    if( (past->past_InputDeviceID != paNoDevice) && (past->past_NumInputChannels > 0) )
     {
-        result = PaHost_OpenInputStream( stream );
+        result = PaHost_OpenInputStream( past );
         if( result < 0 ) goto error;
     }
-
-    Pa_InitializeCpuUsageScalar( stream );
-
+    /* Calculate scalar used in CPULoad calculation. */
+    {
+        LARGE_INTEGER frequency;
+        if( QueryPerformanceFrequency( &frequency ) == 0 )
+        {
+            pahsc->pahsc_InverseTicksPerHostBuffer = 0.0;
+        }
+        else
+        {
+            pahsc->pahsc_InverseTicksPerHostBuffer = past->past_SampleRate /
+                    ( (double)frequency.QuadPart * past->past_FramesPerUserBuffer * pahsc->pahsc_UserBuffersPerHostBuffer );
+            DBUG(("pahsc_InverseTicksPerHostBuffer = %g\n", pahsc->pahsc_InverseTicksPerHostBuffer ));
+        }
+    }
     return result;
-
 error:
-    PaHost_CloseStream( stream );
+    PaHost_CloseStream( past );
     return result;
 }
 /*************************************************************************/
-PaError PaHost_StartOutput( internalPortAudioStream *stream )
+PaError PaHost_StartOutput( internalPortAudioStream *past )
 {
+    MMRESULT         mr;
+    PaHostSoundControl *pahsc;
     PaError          result = paNoError;
-    MMRESULT         mmresult;
     int              i;
-    PaWMMEStreamData *wmmeStreamData = PaHost_GetWMMEStreamData( stream );
-
-    if( wmmeStreamData == NULL ) return paInternalError;
-
-    if( stream->past_OutputDeviceID != paNoDevice )
+    pahsc = (PaHostSoundControl *) past->past_DeviceData;
+    if( past->past_OutputDeviceID != paNoDevice )
     {
-        if( (mmresult = waveOutPause( wmmeStreamData->hWaveOut )) != MMSYSERR_NOERROR )
+        if( (mr = waveOutPause( pahsc->pahsc_HWaveOut )) != MMSYSERR_NOERROR )
         {
             result = paHostError;
-            sPaHostError = mmresult;
+            sPaHostError = mr;
             goto error;
         }
-        for( i=0; i<wmmeStreamData->numHostBuffers; i++ )
+        for( i=0; i<pahsc->pahsc_NumHostBuffers; i++ )
         {
-            ZeroMemory( wmmeStreamData->outputBuffers[i].lpData, wmmeStreamData->outputBuffers[i].dwBufferLength );
-            mmresult = waveOutWrite( wmmeStreamData->hWaveOut, &wmmeStreamData->outputBuffers[i], sizeof(WAVEHDR) );
-            if( mmresult != MMSYSERR_NOERROR )
+            ZeroMemory( pahsc->pahsc_OutputBuffers[i].lpData, pahsc->pahsc_OutputBuffers[i].dwBufferLength );
+            mr = waveOutWrite( pahsc->pahsc_HWaveOut, &pahsc->pahsc_OutputBuffers[i], sizeof(WAVEHDR) );
+            if( mr != MMSYSERR_NOERROR )
             {
                 result = paHostError;
-                sPaHostError = mmresult;
+                sPaHostError = mr;
                 goto error;
             }
-            stream->past_FrameCount += wmmeStreamData->framesPerHostBuffer;
+            past->past_FrameCount += pahsc->pahsc_FramesPerHostBuffer;
         }
-        wmmeStreamData->currentOutputBuffer = 0;
-        if( (mmresult = waveOutRestart( wmmeStreamData->hWaveOut )) != MMSYSERR_NOERROR )
+        pahsc->pahsc_CurrentOutputBuffer = 0;
+        if( (mr = waveOutRestart( pahsc->pahsc_HWaveOut )) != MMSYSERR_NOERROR )
         {
             result = paHostError;
-            sPaHostError = mmresult;
+            sPaHostError = mr;
             goto error;
         }
     }
-
+    DBUG(("PaHost_StartOutput: DSW_StartOutput returned = 0x%X.\n", hr));
 error:
-    DBUG(("PaHost_StartOutput: wave returned mmresult = 0x%X.\n", mmresult));
     return result;
 }
 /*************************************************************************/
-PaError PaHost_StartInput( internalPortAudioStream *internalStream )
+PaError PaHost_StartInput( internalPortAudioStream *past )
 {
     PaError          result = paNoError;
-    MMRESULT         mmresult;
+    MMRESULT         mr;
     int              i;
-    PaWMMEStreamData *wmmeStreamData = PaHost_GetWMMEStreamData( internalStream );
-
-    if( wmmeStreamData == NULL ) return paInternalError;
-
-    if( internalStream->past_InputDeviceID != paNoDevice )
+    PaHostSoundControl *pahsc;
+    pahsc = (PaHostSoundControl *) past->past_DeviceData;
+    if( past->past_InputDeviceID != paNoDevice )
     {
-        for( i=0; i<wmmeStreamData->numHostBuffers; i++ )
+        for( i=0; i<pahsc->pahsc_NumHostBuffers; i++ )
         {
-            mmresult = waveInAddBuffer( wmmeStreamData->hWaveIn, &wmmeStreamData->inputBuffers[i], sizeof(WAVEHDR) );
-            if( mmresult != MMSYSERR_NOERROR )
+            mr = waveInAddBuffer( pahsc->pahsc_HWaveIn, &pahsc->pahsc_InputBuffers[i], sizeof(WAVEHDR) );
+            if( mr != MMSYSERR_NOERROR )
             {
                 result = paHostError;
-                sPaHostError = mmresult;
+                sPaHostError = mr;
                 goto error;
             }
         }
-        wmmeStreamData->currentInputBuffer = 0;
-        mmresult = waveInStart( wmmeStreamData->hWaveIn );
-        DBUG(("Pa_StartStream: waveInStart returned = 0x%X.\n", mmresult));
-        if( mmresult != MMSYSERR_NOERROR )
+        pahsc->pahsc_CurrentInputBuffer = 0;
+        mr = waveInStart( pahsc->pahsc_HWaveIn );
+        DBUG(("Pa_StartStream: waveInStart returned = 0x%X.\n", hr));
+        if( mr != MMSYSERR_NOERROR )
         {
             result = paHostError;
-            sPaHostError = mmresult;
+            sPaHostError = mr;
             goto error;
         }
     }
-
 error:
     return result;
 }
 /*************************************************************************/
-PaError PaHost_StartEngine( internalPortAudioStream *stream )
+PaError PaHost_StartEngine( internalPortAudioStream *past )
 {
     PaError             result = paNoError;
-    PaWMMEStreamData *wmmeStreamData = PaHost_GetWMMEStreamData( stream );
+    PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;
 #if PA_USE_TIMER_CALLBACK
     int                 resolution;
     int                 bufsPerTimerCallback;
     int                 msecPerBuffer;
 #endif /* PA_USE_TIMER_CALLBACK */
 
-    if( wmmeStreamData == NULL ) return paInternalError;
-
-    stream->past_StopSoon = 0;
-    stream->past_StopNow = 0;
-    stream->past_IsActive = 1;
-    wmmeStreamData->framesPlayed = 0.0;
-    wmmeStreamData->lastPosition = 0;
+    past->past_StopSoon = 0;
+    past->past_StopNow = 0;
+    past->past_IsActive = 1;
+    pahsc->pahsc_FramesPlayed = 0.0;
+    pahsc->pahsc_LastPosition = 0;
 #if PA_TRACE_START_STOP
     AddTraceMessage( "PaHost_StartEngine: TimeSlice() returned ", result );
 #endif
 #if PA_USE_TIMER_CALLBACK
     /* Create timer that will wake us up so we can fill the DSound buffer. */
-    bufsPerTimerCallback = wmmeStreamData->numHostBuffers/4;
+    bufsPerTimerCallback = pahsc->pahsc_NumHostBuffers/4;
     if( bufsPerTimerCallback < 1 ) bufsPerTimerCallback = 1;
     if( bufsPerTimerCallback < 1 ) bufsPerTimerCallback = 1;
     msecPerBuffer = (1000 * bufsPerTimerCallback *
-                     wmmeStreamData->userBuffersPerHostBuffer *
-                     internalStream->past_FramesPerUserBuffer ) / (int) internalStream->past_SampleRate;
+                     pahsc->pahsc_UserBuffersPerHostBuffer *
+                     past->past_FramesPerUserBuffer ) / (int) past->past_SampleRate;
     if( msecPerBuffer < 10 ) msecPerBuffer = 10;
     else if( msecPerBuffer > 100 ) msecPerBuffer = 100;
     resolution = msecPerBuffer/4;
-    wmmeStreamData->timerID = timeSetEvent( msecPerBuffer, resolution,
+    pahsc->pahsc_TimerID = timeSetEvent( msecPerBuffer, resolution,
                                          (LPTIMECALLBACK) Pa_TimerCallback,
-                                         (DWORD) stream, TIME_PERIODIC );
-    if( wmmeStreamData->timerID == 0 )
+                                         (DWORD) past, TIME_PERIODIC );
+    if( pahsc->pahsc_TimerID == 0 )
     {
         result = paHostError;
         sPaHostError = GetLastError();;
         goto error;
     }
 #else /* PA_USE_TIMER_CALLBACK */
-    ResetEvent( wmmeStreamData->abortEvent );
+    ResetEvent( pahsc->pahsc_AbortEvent );
     /* Create thread that waits for audio buffers to be ready for processing. */
-    wmmeStreamData->engineThread = CreateThread( 0, 0, WinMMPa_OutputThreadProc, stream, 0, &wmmeStreamData->engineThreadID );
-    if( wmmeStreamData->engineThread == NULL )
+    pahsc->pahsc_EngineThread = CreateThread( 0, 0, WinMMPa_OutputThreadProc, past, 0, &pahsc->pahsc_EngineThreadID );
+    if( pahsc->pahsc_EngineThread == NULL )
     {
         result = paHostError;
         sPaHostError = GetLastError();;
         goto error;
     }
 #if PA_TRACE_START_STOP
-    AddTraceMessage( "PaHost_StartEngine: thread ", (int) wmmeStreamData->engineThread );
+    AddTraceMessage( "PaHost_StartEngine: thread ", (int) pahsc->pahsc_EngineThread );
 #endif
     /* I used to pass the thread which was failing. I now pass GetCurrentProcess().
-     * This fix could improve latency for some applications. It could also result in CPU
-     * starvation if the callback did too much processing.
-     * I also added result checks, so we might see more failures at initialization.
-     * Thanks to Alberto di Bene for spotting this.
-     */
+    ** This fix could improve latency for some applications. It could also result in CPU
+    ** starvation if the callback did too much processing.
+    ** I also added result checks, so we might see more failures at initialization.
+    ** Thanks to Alberto di Bene for spotting this.
+    */
     if( !SetPriorityClass( GetCurrentProcess(), HIGH_PRIORITY_CLASS ) ) /* PLB20010816 */
     {
         result = paHostError;
         sPaHostError = GetLastError();;
         goto error;
     }
-    if( !SetThreadPriority( wmmeStreamData->engineThread, THREAD_PRIORITY_HIGHEST ) )
+    if( !SetThreadPriority( pahsc->pahsc_EngineThread, THREAD_PRIORITY_HIGHEST ) )
     {
         result = paHostError;
         sPaHostError = GetLastError();;
         goto error;
     }
 #endif
-
 error:
     return result;
 }
+
 /*************************************************************************/
-PaError PaHost_StopEngine( internalPortAudioStream *internalStream, int abort )
+PaError PaHost_StopEngine( internalPortAudioStream *past, int abort )
 {
     int timeOut;
-    PaWMMEStreamData *wmmeStreamData = PaHost_GetWMMEStreamData( internalStream );
-
-    if( wmmeStreamData == NULL ) return 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. */
-    internalStream->past_StopSoon = 1;
+    past->past_StopSoon = 1;
     /* If aborting, tell background thread to stop NOW! */
-    if( abort ) internalStream->past_StopNow = 1;
+    if( abort ) past->past_StopNow = 1;
 
     /* Calculate timeOut longer than longest time it could take to play all buffers. */
-    timeOut = (DWORD) (1500.0 * PaHost_GetTotalBufferFrames( internalStream ) / internalStream->past_SampleRate);
+    timeOut = (DWORD) (1500.0 * PaHost_GetTotalBufferFrames( past ) / past->past_SampleRate);
     if( timeOut < MIN_TIMEOUT_MSEC ) timeOut = MIN_TIMEOUT_MSEC;
 
 #if PA_USE_TIMER_CALLBACK
-    if( (internalStream->past_OutputDeviceID != paNoDevice) &&
-            internalStream->past_IsActive &&
-            (wmmeStreamData->timerID != 0) )
+    if( (past->past_OutputDeviceID != paNoDevice) &&
+            past->past_IsActive &&
+            (pahsc->pahsc_TimerID != 0) )
     {
         /* Wait for IsActive to drop. */
-        while( (internalStream->past_IsActive) && (timeOut > 0) )
+        while( (past->past_IsActive) && (timeOut > 0) )
         {
             Sleep(10);
             timeOut -= 10;
         }
-        timeKillEvent( wmmeStreamData->timerID );  /* Stop callback timer. */
-        wmmeStreamData->timerID = 0;
+        timeKillEvent(pahsc->pahsc_TimerID);  /* Stop callback timer. */
+        pahsc->pahsc_TimerID = 0;
     }
 #else /* PA_USE_TIMER_CALLBACK */
 #if PA_TRACE_START_STOP
-    AddTraceMessage( "PaHost_StopEngine: thread ", (int) wmmeStreamData->engineThread );
+    AddTraceMessage( "PaHost_StopEngine: thread ", (int) pahsc->pahsc_EngineThread );
 #endif
-    if( (internalStream->past_OutputDeviceID != paNoDevice) &&
-            (internalStream->past_IsActive) &&
-            (wmmeStreamData->engineThread != NULL) )
+    if( (past->past_OutputDeviceID != paNoDevice) &&
+            (past->past_IsActive) &&
+            (pahsc->pahsc_EngineThread != NULL) )
     {
         DWORD got;
         /* Tell background thread to stop generating more data and to let current data play out. */
         DBUG(("PaHost_StopEngine: waiting for background thread.\n"));
-        got = WaitForSingleObject( wmmeStreamData->engineThread, timeOut );
+        got = WaitForSingleObject( pahsc->pahsc_EngineThread, timeOut );
         if( got == WAIT_TIMEOUT )
         {
             ERR_RPT(("PaHost_StopEngine: timed out while waiting for background thread to finish.\n"));
             return paTimedOut;
         }
-        CloseHandle( wmmeStreamData->engineThread );
-        wmmeStreamData->engineThread = NULL;
+        CloseHandle( pahsc->pahsc_EngineThread );
+        pahsc->pahsc_EngineThread = NULL;
     }
 #endif /* PA_USE_TIMER_CALLBACK */
 
-    internalStream->past_IsActive = 0;
+    past->past_IsActive = 0;
     return paNoError;
 }
 /*************************************************************************/
-PaError PaHost_StopInput( internalPortAudioStream *stream, int abort )
+PaError PaHost_StopInput( internalPortAudioStream *past, int abort )
 {
-    MMRESULT mmresult;
-    PaWMMEStreamData *wmmeStreamData = PaHost_GetWMMEStreamData( stream );
-
-    if( wmmeStreamData == NULL ) return paNoError; /* FIXME: why return paNoError? */
-    (void) abort; /* unused parameter */
-
-    if( wmmeStreamData->hWaveIn != NULL )
+    MMRESULT mr;
+    PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;
+    if( pahsc == NULL ) return paNoError;
+    (void) abort;
+    if( pahsc->pahsc_HWaveIn != NULL )
     {
-        mmresult = waveInReset( wmmeStreamData->hWaveIn );
-        if( mmresult != MMSYSERR_NOERROR )
+        mr = waveInReset( pahsc->pahsc_HWaveIn );
+        if( mr != MMSYSERR_NOERROR )
         {
-            sPaHostError = mmresult;
+            sPaHostError = mr;
             return paHostError;
         }
     }
     return paNoError;
 }
 /*************************************************************************/
-PaError PaHost_StopOutput( internalPortAudioStream *internalStream, int abort )
+PaError PaHost_StopOutput( internalPortAudioStream *past, int abort )
 {
-    MMRESULT mmresult;
-    PaWMMEStreamData *wmmeStreamData = PaHost_GetWMMEStreamData( internalStream );
-
-    if( wmmeStreamData == NULL ) return paNoError;    /* FIXME: why return paNoError? */
-    (void) abort;   /* unused parameter */
-
+    MMRESULT mr;
+    PaHostSoundControl *pahsc;
+    pahsc = (PaHostSoundControl *) past->past_DeviceData;
+    if( pahsc == NULL ) return paNoError;
+    (void) abort;
 #if PA_TRACE_START_STOP
-    AddTraceMessage( "PaHost_StopOutput: hWaveOut ", (int) wmmeStreamData->hWaveOut );
+    AddTraceMessage( "PaHost_StopOutput: pahsc_HWaveOut ", (int) pahsc->pahsc_HWaveOut );
 #endif
-    if( wmmeStreamData->hWaveOut != NULL )
+    if( pahsc->pahsc_HWaveOut != NULL )
     {
-        mmresult = waveOutReset( wmmeStreamData->hWaveOut );
-        if( mmresult != MMSYSERR_NOERROR )
+        mr = waveOutReset( pahsc->pahsc_HWaveOut );
+        if( mr != MMSYSERR_NOERROR )
         {
-            sPaHostError = mmresult;
+            sPaHostError = mr;
             return paHostError;
         }
     }
     return paNoError;
 }
 /*******************************************************************/
-PaError PaHost_CloseStream( internalPortAudioStream *stream )
+PaError PaHost_CloseStream( internalPortAudioStream   *past )
 {
-    int i;
-    PaWMMEStreamData *wmmeStreamData = PaHost_GetWMMEStreamData( stream );
-
-    if( stream == NULL ) return paBadStreamPtr;
-    if( wmmeStreamData == NULL ) return paNoError;   /* FIXME: why return no error? */
-
+    int                 i;
+    PaHostSoundControl *pahsc;
+    if( past == NULL ) return paBadStreamPtr;
+    pahsc = (PaHostSoundControl *) past->past_DeviceData;
+    if( pahsc == NULL ) return paNoError;
 #if PA_TRACE_START_STOP
-    AddTraceMessage( "PaHost_CloseStream: hWaveOut ", (int) wmmeStreamData->hWaveOut );
+    AddTraceMessage( "PaHost_CloseStream: pahsc_HWaveOut ", (int) pahsc->pahsc_HWaveOut );
 #endif
     /* Free data and device for output. */
-    if( wmmeStreamData->hWaveOut )
+    if( pahsc->pahsc_HWaveOut )
     {
-        if( wmmeStreamData->outputBuffers )
+        if( pahsc->pahsc_OutputBuffers )
         {
-            for( i=0; i<wmmeStreamData->numHostBuffers; i++ )
+            for( i=0; i<pahsc->pahsc_NumHostBuffers; i++ )
             {
-                waveOutUnprepareHeader( wmmeStreamData->hWaveOut, &wmmeStreamData->outputBuffers[i], sizeof(WAVEHDR) );
-                PaHost_FreeTrackedMemory( wmmeStreamData->outputBuffers[i].lpData ); /* MEM */
+                waveOutUnprepareHeader( pahsc->pahsc_HWaveOut, &pahsc->pahsc_OutputBuffers[i], sizeof(WAVEHDR) );
+                GlobalFree( pahsc->pahsc_OutputBuffers[i].lpData ); /* MEM */
             }
-            PaHost_FreeTrackedMemory( wmmeStreamData->outputBuffers ); /* MEM */
+            GlobalFree( pahsc->pahsc_OutputBuffers ); /* MEM */
         }
-        waveOutClose( wmmeStreamData->hWaveOut );
+        waveOutClose( pahsc->pahsc_HWaveOut );
     }
     /* Free data and device for input. */
-    if( wmmeStreamData->hWaveIn )
+    if( pahsc->pahsc_HWaveIn )
     {
-        if( wmmeStreamData->inputBuffers )
+        if( pahsc->pahsc_InputBuffers )
         {
-            for( i=0; i<wmmeStreamData->numHostBuffers; i++ )
+            for( i=0; i<pahsc->pahsc_NumHostBuffers; i++ )
             {
-                waveInUnprepareHeader( wmmeStreamData->hWaveIn, &wmmeStreamData->inputBuffers[i], sizeof(WAVEHDR) );
-                PaHost_FreeTrackedMemory( wmmeStreamData->inputBuffers[i].lpData ); /* MEM */
+                waveInUnprepareHeader( pahsc->pahsc_HWaveIn, &pahsc->pahsc_InputBuffers[i], sizeof(WAVEHDR) );
+                GlobalFree( pahsc->pahsc_InputBuffers[i].lpData ); /* MEM */
             }
-            PaHost_FreeTrackedMemory( wmmeStreamData->inputBuffers ); /* MEM */
+            GlobalFree( pahsc->pahsc_InputBuffers ); /* MEM */
         }
-        waveInClose( wmmeStreamData->hWaveIn );
+        waveInClose( pahsc->pahsc_HWaveIn );
     }
 #if (PA_USE_TIMER_CALLBACK == 0)
-    if( wmmeStreamData->abortEventInited ) CloseHandle( wmmeStreamData->abortEvent );
-    if( wmmeStreamData->bufferEventInited ) CloseHandle( wmmeStreamData->bufferEvent );
+    if( pahsc->pahsc_AbortEventInited ) CloseHandle( pahsc->pahsc_AbortEvent );
+    if( pahsc->pahsc_BufferEventInited ) CloseHandle( pahsc->pahsc_BufferEvent );
 #endif
-    if( wmmeStreamData->streamLockInited )
-        DeleteCriticalSection( &wmmeStreamData->streamLock );
-
-    PaHost_FreeWMMEStreamData( stream );
-
+    if( pahsc->pahsc_StreamLockInited )
+        DeleteCriticalSection( &pahsc->pahsc_StreamLock );
+    PaHost_FreeFastMemory( pahsc, sizeof(PaHostSoundControl) ); /* MEM */
+    past->past_DeviceData = NULL;
     return paNoError;
 }
 /*************************************************************************
- * 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 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.
- */
+** 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 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.
+*/
 #define PA_LATENCY_ENV_NAME  ("PA_MIN_LATENCY_MSEC")
 int Pa_GetMinNumBuffers( int framesPerBuffer, double sampleRate )
 {
     char      envbuf[PA_ENV_BUF_SIZE];
+    DWORD     hostVersion;
     DWORD     hresult;
     int       minLatencyMsec = 0;
     double    msecPerBuffer = (1000.0 * framesPerBuffer) / sampleRate;
     int       minBuffers;
-
     /* Let user determine minimal latency by setting environment variable. */
     hresult = GetEnvironmentVariable( PA_LATENCY_ENV_NAME, envbuf, PA_ENV_BUF_SIZE );
     if( (hresult > 0) && (hresult < PA_ENV_BUF_SIZE) )
     {
-        minLatencyMsec = atoi( envbuf );   /* REVIEW: will we crash if the environment variable contains some nasty value? */
+        minLatencyMsec = atoi( envbuf );
     }
     else
     {
-        /* Set minimal latency based on whether NT or other OS.
+        /* Set minimal latency based on whether NT or Win95.
          * NT has higher latency.
          */
-        OSVERSIONINFO osvi;
-               osvi.dwOSVersionInfoSize = sizeof( osvi );
-               GetVersionEx( &osvi );
-        DBUG(("PA - PlatformId = 0x%x\n", osvi.dwPlatformId ));
-        DBUG(("PA - MajorVersion = 0x%x\n", osvi.dwMajorVersion ));
-        DBUG(("PA - MinorVersion = 0x%x\n", osvi.dwMinorVersion ));
-        /* Check for NT */
-               if( (osvi.dwMajorVersion == 4) && (osvi.dwPlatformId == 2) )
-               {
-                       minLatencyMsec = PA_WIN_NT_LATENCY;
-               }
-               else if(osvi.dwMajorVersion >= 5)
-               {
-                       minLatencyMsec = PA_WIN_WDM_LATENCY;
-               }
-               else
-               {
-                       minLatencyMsec = PA_WIN_9X_LATENCY;
-               }
+        hostVersion = GetVersion();
+        /* High bit clear if NT */
+        minLatencyMsec = ( (hostVersion & 0x80000000) == 0 ) ? PA_WIN_NT_LATENCY : PA_WIN_9X_LATENCY  ;
 #if PA_USE_HIGH_LATENCY
         PRINT(("PA - Minimum Latency set to %d msec!\n", minLatencyMsec ));
 #endif
@@ -1565,12 +1392,11 @@ int Pa_GetMinNumBuffers( int framesPerBuffer, double sampleRate )
     return minBuffers;
 }
 /*************************************************************************
- * Cleanup device info.
- */
+** Cleanup device info.
+*/
 PaError PaHost_Term( void )
 {
     int i;
-
     if( sNumDevices > 0 )
     {
         if( sDevicePtrs != NULL )
@@ -1579,21 +1405,16 @@ PaError PaHost_Term( void )
             {
                 if( sDevicePtrs[i] != NULL )
                 {
-                    PaHost_FreeTrackedMemory( (char*)sDevicePtrs[i]->name ); /* MEM */
-                    PaHost_FreeTrackedMemory( (void*)sDevicePtrs[i]->sampleRates ); /* MEM */
-                    PaHost_FreeTrackedMemory( sDevicePtrs[i] ); /* MEM */
+                    GlobalFree( (char*)sDevicePtrs[i]->name ); /* MEM */
+                    GlobalFree( (void*)sDevicePtrs[i]->sampleRates ); /* MEM */
+                    GlobalFree( sDevicePtrs[i] ); /* MEM */
                 }
             }
-            PaHost_FreeTrackedMemory( sDevicePtrs ); /* MEM */
+            GlobalFree( sDevicePtrs ); /* MEM */
             sDevicePtrs = NULL;
         }
         sNumDevices = 0;
     }
-
-#if PA_TRACK_MEMORY
-    PRINT(("PaHost_Term: sNumAllocations = %d\n", sNumAllocations ));
-#endif
-
     return paNoError;
 }
 /*************************************************************************/
@@ -1602,7 +1423,6 @@ void Pa_Sleep( long msec )
     Sleep( msec );
 }
 /*************************************************************************
-FIXME: the following memory allocation routines should not be declared here
  * 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.
@@ -1611,7 +1431,8 @@ FIXME: the following memory allocation routines should not be declared here
  */
 void *PaHost_AllocateFastMemory( long numBytes )
 {
-    return PaHost_AllocateTrackedMemory( numBytes ); /* FIXME - do we need physical memory? Use VirtualLock() */ /* MEM */
+    void *addr = GlobalAlloc( GPTR, numBytes ); /* FIXME - do we need physical memory? Use VirtualLock() */ /* MEM */
+    return addr;
 }
 /*************************************************************************
  * Free memory that could be accessed in real-time.
@@ -1619,89 +1440,54 @@ void *PaHost_AllocateFastMemory( long numBytes )
  */
 void PaHost_FreeFastMemory( void *addr, long numBytes )
 {
-    (void) numBytes; /* unused parameter */
-    
-    PaHost_FreeTrackedMemory( addr ); /* MEM */
-}
-
-/*************************************************************************
- * Track memory allocations to avoid leaks.
- */
-static void *PaHost_AllocateTrackedMemory( long numBytes )
-{
-    void *result = GlobalAlloc( GPTR, numBytes ); /* MEM */
-
-#if PA_TRACK_MEMORY
-    if( result != NULL ) sNumAllocations += 1;
-#endif
-    return result;
-}
-
-static void PaHost_FreeTrackedMemory( void *addr )
-{
-    if( addr != NULL )
-    {
-        GlobalFree( addr ); /* MEM */
-#if PA_TRACK_MEMORY
-        sNumAllocations -= 1;
-#endif
-    }
+    if( addr != NULL ) GlobalFree( addr ); /* MEM */
 }
-
 /***********************************************************************/
-PaError PaHost_StreamActive( internalPortAudioStream *internalStream )
+PaError PaHost_StreamActive( internalPortAudioStream   *past )
 {
-    if( internalStream == NULL ) return paBadStreamPtr;
-
-    return (PaError) internalStream->past_IsActive;
+    PaHostSoundControl *pahsc;
+    if( past == NULL ) return paBadStreamPtr;
+    pahsc = (PaHostSoundControl *) past->past_DeviceData;
+    if( pahsc == NULL ) return paInternalError;
+    return (PaError) past->past_IsActive;
 }
 /*************************************************************************
  * This must be called periodically because mmtime.u.sample
  * is a DWORD and can wrap and lose sync after a few hours.
  */
-static PaError PaHost_UpdateStreamTime( PaWMMEStreamData *wmmeStreamData )
+static PaError PaHost_UpdateStreamTime( PaHostSoundControl *pahsc )
 {
-    MMRESULT  mmresult;
+    MMRESULT  mr;
     MMTIME    mmtime;
     mmtime.wType = TIME_SAMPLES;
-
-    if( wmmeStreamData->hWaveOut != NULL )
+    if( pahsc->pahsc_HWaveOut != NULL )
     {
-        mmresult = waveOutGetPosition( wmmeStreamData->hWaveOut, &mmtime, sizeof(mmtime) );
+        mr = waveOutGetPosition( pahsc->pahsc_HWaveOut, &mmtime, sizeof(mmtime) );
     }
     else
     {
-        mmresult = waveInGetPosition( wmmeStreamData->hWaveIn, &mmtime, sizeof(mmtime) );
+        mr = waveInGetPosition( pahsc->pahsc_HWaveIn, &mmtime, sizeof(mmtime) );
     }
-    
-    if( mmresult != MMSYSERR_NOERROR )
+    if( mr != MMSYSERR_NOERROR )
     {
-        sPaHostError = mmresult;
+        sPaHostError = mr;
         return paHostError;
     }
-    
-    /* This data has two variables and is shared by foreground and background.
-     * So we need to make it thread safe. */
-    EnterCriticalSection( &wmmeStreamData->streamLock );
-    wmmeStreamData->framesPlayed += ((long)mmtime.u.sample) - wmmeStreamData->lastPosition;
-    wmmeStreamData->lastPosition = (long)mmtime.u.sample;
-    LeaveCriticalSection( &wmmeStreamData->streamLock );
-    
+    /* This data has two variables and is shared by foreground and background. */
+    /* So we need to make it thread safe. */
+    EnterCriticalSection( &pahsc->pahsc_StreamLock );
+    pahsc->pahsc_FramesPlayed += ((long)mmtime.u.sample) - pahsc->pahsc_LastPosition;
+    pahsc->pahsc_LastPosition = (long)mmtime.u.sample;
+    LeaveCriticalSection( &pahsc->pahsc_StreamLock );
     return paNoError;
 }
 /*************************************************************************/
 PaTimestamp Pa_StreamTime( PortAudioStream *stream )
 {
-    internalPortAudioStream *internalStream = PaHost_GetStreamRepresentation( stream );
-    PaWMMEStreamData *wmmeStreamData = PaHost_GetWMMEStreamData( internalStream );
-
-    if( internalStream == NULL ) return paBadStreamPtr;
-    if( wmmeStreamData == NULL ) return paInternalError;
-
-    PaHost_UpdateStreamTime( wmmeStreamData );
-    return wmmeStreamData->framesPlayed;
+    PaHostSoundControl *pahsc;
+    internalPortAudioStream   *past = (internalPortAudioStream *) stream;
+    if( past == NULL ) return paBadStreamPtr;
+    pahsc = (PaHostSoundControl *) past->past_DeviceData;
+    PaHost_UpdateStreamTime( pahsc );
+    return pahsc->pahsc_FramesPlayed;
 }
-/*************************************************************************/
-
-
-
index 7f7e886ac0e53f9f4324ec4db2ad511c66c20dde..245e19c50ff71d954213d614a69cefcf6f3d52f6 100644 (file)
 ** full duplex audio (simultaneous record and playback).
 ** And some only support full duplex at lower sample rates.
 */
-#define SAMPLE_RATE          (44100)
-#define NUM_SECONDS              (5)
-#define SAMPLES_PER_FRAME        (2)
-#define FRAMES_PER_BLOCK        (64)
+#define SAMPLE_RATE         (22050)
+#define NUM_SECONDS             (15)
+#define SAMPLES_PER_FRAME       (2)
 
 /* Select whether we will use floats or shorts. */
 #if 1
@@ -63,7 +62,7 @@ int main(void);
 int main(void)
 {
     int      i;
-    SAMPLE   samples[SAMPLES_PER_FRAME * FRAMES_PER_BLOCK];
+    SAMPLE   samples[SAMPLES_PER_FRAME];
     PaError  err;
     PABLIO_Stream     *aStream;
 
@@ -76,12 +75,13 @@ int main(void)
     if( err != paNoError ) goto error;
 
     /* Process samples in the foreground. */
-    for( i=0; i<(NUM_SECONDS * SAMPLE_RATE); i += FRAMES_PER_BLOCK )
+    for( i=0; i<(NUM_SECONDS * SAMPLE_RATE); i++ )
     {
-        /* Read one block of data into sample array from audio input. */
-        ReadAudioStream( aStream, samples, FRAMES_PER_BLOCK );
-        /* Write that same block of data to output. */
-        WriteAudioStream( aStream, samples, FRAMES_PER_BLOCK );
+        /* Read one frame of data into sample array from audio input. */
+        ReadAudioStream( aStream, samples, 1 );
+        /* Write that same frame of data to output. */
+        /* samples[1] = (i&256) * (1.0f/256.0f); /* sawtooth */
+        WriteAudioStream( aStream, samples, 1 );
     }
 
     CloseAudioStream( aStream );
diff --git a/testcvs/changeme.txt b/testcvs/changeme.txt
deleted file mode 100644 (file)
index 3a69b98..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-This is just a dopy little file used to test the CVS repository.
-Feel free to trash this file.
-Minor change.
-Another tweak.
-philburk tweak
-stephane test
-Phil changed this again on 2/21/02. Yawn...
-pieter test (MacCVS Pro 2.5b2)
-phil says hi
diff --git a/testcvs/stuff/info.txt b/testcvs/stuff/info.txt
deleted file mode 100644 (file)
index d557202..0000000
+++ /dev/null
@@ -1 +0,0 @@
-interesting info